В этом посте я научу вас небольшому изящному трюку, который вы обязательно должны использовать - если вы еще этого не сделали - для очистки импорта JavaScript.
Недавно я сделал YouTube-видео о компонентах Sub Rendering React, которое было основано на сообщении в блоге, которое я написал здесь. Какой-то крутой парень прокомментировал видео, потому что он был крутым, комментируя (намек, подмигнуть, подтолкнуть, подтолкнуть). В любом случае, передайте привет крутому парню, который называет себя Max Equation. Он оставил этот обнадеживающий комментарий, который вдохновил меня на написание этого сообщения в блоге:
Я расскажу об интеграции TypeScript с ReactJS в другой раз. Но в этом посте я хотел бы обратиться к концепции модульного построения функций и классов JavaScript!
Что означает модуляризация в JavaScript?
Что ж, это причудливый, но простой метод, использующий функции import
и export
, поставляемые с ES6. Я регулярно использую это в своей работе по React, но это то, что можно использовать в любом фреймворке JavaScript.
Чтобы объяснить эту концепцию, нам сначала нужно рассмотреть, как работает импорт и экспорт ES6. Давайте посмотрим на пример простого функционального компонента React без сохранения состояния, который отображает компоненты Header
, Content
и Footer
. Эти компоненты определены в трех отдельных файлах в папке components
. Папка components
находится на том же уровне каталога, что и наш простой компонент, который мы назовем MyComponent
в демонстрационных целях. Вот наша реализация MyComponent
:
import React from 'react'; import Header from './components/header; import Content from './components/content; import Footer from './components/footer;
const MyComponent = () => ( <> <Header /> <Content /> <Footer /> </> );
export default MyComponent;
Я хочу сосредоточиться на import
разделе этого компонента, чтобы упростить его. Если вы не знакомы с синтаксисом <>...</>
, тогда прочтите мой пост о React Fragments.
В этом примере компоненты Header
, Content
и Footer
имеют очень похожую реализацию. Давайте сосредоточимся на компоненте Header
. Этот Header
компонент является либо экспортируемой функцией по умолчанию в файле в папке components
с именем header.js
. В противном случае это экспортируемая функция по умолчанию в index.js
файле в папке с именем header
внутри папки components
. Хорошо, это был полный рот… Ты все еще со мной?
Обычно ссылка на './header'
- это либо файл header.js
, либо файл index.js
внутри папки header
. Что ж, если вы не поняли сейчас, я не знаю, что еще сказать. Я сделаю видео на YouTube через несколько дней, чтобы попытаться объяснить это. Вы можете подписаться на него по этой ссылке.
Экспорт по умолчанию и экспорт именованной функции / класса
Помните, я сказал, что эти импортированные компоненты являются функциями экспорта по умолчанию для файлов, из которых они были экспортированы? Что ж, давайте посмотрим на файл header.js
, чтобы понять, что я имею в виду:
const Header = () => <div>Header</div>;
export default Header;
Мы export default Header;
, поэтому, когда мы импортируем его в наш основной компонент, мы импортируем его следующим образом:
import Header from './components/header';
Не всегда нужно экспортировать данные по умолчанию. Однако общепринятой практикой является использование одной функции или класса для каждого файла и экспорт этой функции или класса по умолчанию. Вы также можете просто экспортировать функцию Header
с именем export следующим образом:
const Header = () => <div>Header</div>;
export Header; // See the 'default' keyword is removed
Вы также можете экспортировать его с таким названием:
export const Header = () => <div>Header</div>;
Что это означает для нашей реализации импорта Header
в основной компонент? Ну, поскольку теперь это именованный экспорт, вам нужно импортировать его, используя фигурные скобки, например:
import { Header } from './components/header';
Но, как я уже упоминал, рекомендуется иметь один класс или функцию для каждого файла, и этот класс или функция должны быть экспортированы по умолчанию.
В чем тогда смысл экспорта именованных функций и классов?
Здесь все становится круто. Представьте, что мы поленились и решили не создавать отдельные файлы для наших Header
, Content
и Footer
компонентов, #screwbestpractices. Что, если бы мы просто экспортировали их все, как указано в index.js
файле в нашей папке компонентов, как в этом примере ниже?
export const Header = () => <div>Header</div>;
export const Content = () => <div>Content</div>;
export const Footer = () => <div>Footer</div>;
Что ж, это довольно круто, теперь мы можем импортировать их в наш основной компонент следующим образом:
import { Header, Content, Footer } from './components';
И просто в целях обучения, если бы мы сделали то же самое, но экспортировали Header
по умолчанию следующим образом:
const Header = () => <div>Header</div>;
export const Content = () => <div>Content</div>;
export const Footer = () => <div>Footer</div>;
export default Header;
Затем мы импортируем его в наш основной компонент следующим образом:
import Header, { Content, Footer } from './components';
Еще несколько советов по импорту и экспорту:
Последняя вещь. Технически вы можете import
экспортировать класс по умолчанию под любым именем. Например, вы можете импортировать то же самое:
import RandomOtherName, { Content, Footer } from './components';
Или вы можете назвать экспорт по умолчанию как-то еще внутри именованного импорта, например:
import { default as Header, Content, Footer } from './components';
При этом технически не нужно указывать имя для экспорта по умолчанию. Вы могли просто экспортировать свой Header
компонент по умолчанию следующим образом:
export const Content = () => <div>Content</div>;
export const Footer = () => <div>Footer</div>;
export default () => <div>Header</div>;
При этом все равно будут работать те методы импорта, о которых я упоминал выше.
Хорошо, я думаю, это все, что вам нужно знать об импорте и экспорте модулей JavaScript в ES6. Но большинство из этих практик не очень хороши, когда дело доходит до написания чистого и поддерживаемого кода. Если вы читали какие-либо другие мои сообщения. Вы знаете, что я стремлюсь писать чистый, читаемый и поддерживаемый код. Итак, давайте закончим, поговорив о том, как мы можем импортировать и экспортировать наши компоненты чистым и эффективным способом.
Модуляризация кода в действии!
Как я говорил снова и снова. Обычно рекомендуется иметь один файл для одной функции или класса. Итак, в нашем исходном примере, где мы импортировали экспортируемые по умолчанию функции из разных файлов, мы уже применяли лучшие практики. Реализовано это было так:
import Header from './components/header';
import Content from './components/content';
import Footer from './components/footer';
Это правильно, но замечаете ли вы еще одну общепринятую передовую практику, которой мы здесь пренебрегаем? Если вы думаете о слове «СУХОЙ», то вы правы! «СУХОЙ» означает «Не повторяйся». Вы, вероятно, можете увидеть здесь общую закономерность. Мы импортируем несколько функций из одной папки, но они находятся в разных файлах. Мы можем здесь что-нибудь сделать?
Если мы объединим все наши техники с тем, что у нас есть, мы сможем творить удивительные волшебные вещи! Помните, все наши функции находятся в папке components
, верно? Что, если оставить все как есть и добавить файл index.js
в нашу папку components
, чтобы экспортировать все наши функции по умолчанию как именованные функции в одном месте? Отличная идея! И сделать это легко так:
export { default as Header } from './header';
export { default as Content } from './content';
export { default as Footer } from './footer';
И затем вы можете импортировать их все в основной компонент следующим образом:
import { Header, Content, Footer } from './components';
Это гораздо более чистый способ упорядоченного импорта и экспорта файлов. С помощью этого метода гораздо проще ссылаться на классы и функции.
Еще одно место, где можно применить эту технику
Я считаю, что этот трюк действительно пригодится для разделения многих вспомогательных функций на несколько файлов вместо того, чтобы хранить их все в одном файле. Это упрощает поиск вспомогательных функций при навигации в среде IDE, а также значительно упрощает определение вспомогательных функций для модульных тестов.
Заключение
Мы многое здесь рассмотрели, и я надеюсь, что вы многому научились. Если вы уже знакомы с этой техникой, я надеюсь, что вы сможете использовать этот пост, чтобы научить коллег и друзей.
Мое вдохновение для написания таких сообщений пришло из Code Complete: Практическое руководство по построению программного обеспечения, второе издание. Эта книга стала катализатором роста для многих разработчиков, включая меня. Если у вас нет копии, я настоятельно рекомендую вам сделать себе одолжение и получить ее!
В любом случае! Если вам понравился этот пост, то оставьте лайки и аплодисменты. И если вы хотите быть в курсе других моих материалов, обязательно подпишитесь на меня в Facebook, Twitter, Medium, YouTube и LinkedIn.
Удачного кодирования!
Первоначально опубликовано на www.barrymichaeldoyle.com 10 сентября 2018 г.