Практическо ръководство за ES6 модулите

ES6 модули

Едно от основните предизвикателства при създаването на уеб приложение е колко бързо можете да мащабирате и да отговаряте на нуждите на пазара. Когато търсенето (изискванията) се увеличава, възможностите (характеристиките) също се увеличават. Ето защо е важно да имате солидна архитектурна структура, така че приложението да расте органично. Не искаме да се оказваме в ситуации, в които приложението не може да мащабира, защото всичко в приложението е дълбоко заплетено.

Напишете код, който се изтрива лесно, не се разширява лесно.
- Tef, програмирането е ужасно

В тази статия ще създадем обикновено табло за управление, използвайки ES6 модули, и след това ще представим техники за оптимизация за подобряване на структурата на папките и лесно записване на по-малко код. Нека да видим, защо модулите ES6 са важни и как да го прилагам ефективно.

JavaScript има модули отдавна. Те обаче бяха реализирани чрез библиотеки, а не вградени в езика. ES6 е първият път, в който JavaScript има вградени модули (източник).

TL; DR - Ако искате да видите практически пример, когато създаваме табло с помощта на ES6 модули от архитектурно оформление, преминете към раздел 4.

Ето какво ще адресираме

  1. Защо са необходими модули ES6
  2. Обратно в дните, когато скриптите се зареждаха ръчно
  3. Как работят модулите на ES6 (внос срещу износ)
  4. Нека изградим табло с модули
  5. Техники за оптимизация за пример на таблото
Ако искате да станете по-добър уеб разработчик, да започнете свой собствен бизнес, да преподавате други или да подобрите уменията си за развитие, аз ще публикувам седмични съвети и трикове на най-новите уеб езици.

1. Защо са необходими модули ES6

Нека разгледаме няколко сценария защо модулите са подходящи.

Сценарий 1 - Не преоткривайте колелото

Като разработчици, ние често пресъздаваме вече създадени неща, без дори да сме наясно, или копираме и поставяме неща, за да намалим времето. В крайна сметка тя се добавя и ние оставаме с x брой еднакви копия, разпръснати из приложението. И за всеки път, когато трябва да променим нещо, трябва да го правим x пъти в зависимост от това колко копия имаме.

пример
Например, представете си автомобилна фабрика, която се опитва да преоткрива двигателя всеки път, когато произвежда нова кола, или архитект, започващ от нулата след всяка рисунка. Не е невъзможно да направите това, но тогава какъв е смисълът на знанието, ако не можете да използвате повторно опита, който сте придобили.

Сценарий 2 - Бариера на знанието

Ако системата е дълбоко заплетена и липсва документация, за старите / новите разработчици е трудно да научат как работи приложението и как се свързват нещата.

пример
Например, един програмист трябва да може да види какъв е резултатът от промяната, без да предполага, в противен случай се оказваме с много грешки, без да знаем откъде да започнем. Решение е да използваме модули за капсулиращо поведение, лесно можем да стесним процеса на отстраняване на грешки и бързо да идентифицираме корена на проблема.

Наскоро написах статия за „Разработчици, които постоянно искат да учат нови неща“, със съвети как да подобрят знанията.

Сценарий 3 - Неочаквано поведение

Чрез избягване на отделянето на проблеми (принцип на проектиране), това може да доведе до неочаквано поведение.

пример
Например, да кажем, че някой увеличава силата на звука в колата и това стартира чистачките на предното стъкло. Това е пример за неочаквано поведение, а не нещо, което искаме в нашето приложение.

Накратко, ние се нуждаем от ES6 модули, за да използваме ефективно, поддържаме, отделяме и капсулираме вътрешното поведение от външното поведение. Не става въпрос за усложняване на системата, а за възможността лесно да мащабирате и изтривате неща, без да нарушавате системата.

2. Обратно в дните, когато скриптите са били заредени ръчно

Ако сте правили уеб разработка от няколко години, тогава определено сте срещнали конфликти за зависимост, като например скриптове, които не се зареждат в правилния ред, или че елементите на DOM дървото не могат да бъдат достъпни от JS.

Причината е, че HTML кодът на дадена страница се зарежда в реда, в който се появява, което означава, че не можем да заредим скриптове, преди съдържанието в елемента да е приключило да се зарежда.

Например, ако се опитате да получите достъп до елемент в тага , като използвате document.getElementById („id-name“) и елементът все още не е зареден, тогава получавате неопределена грешка. За да сме сигурни, че скриптите са заредени правилно, можем да използваме отлагане и асинхронизация. Първият ще се увери, че всеки скрипт се зарежда в реда, в който се появява, докато вторият зарежда скрипта, когато стане наличен.

Старомодният начин за решаване на такъв проблем беше да се заредят скриптовете точно преди елемента .

Но в дългосрочен план броят скриптове се добавя и може да се окажем с 10+ скрипта, докато се опитваме да поддържаме конфликти между версии и зависимости.

Разделяне-на-опасения

По принцип зареждането на скриптове, както е показано по-горе, не е добра идея по отношение на производителност, зависимости и поддръжка. Не искаме файлът index.html да носи отговорност за зареждането на всички скриптове - имаме нужда от някаква структура и разделяне на логиката.

Решението е да използваме синтаксиса, декларациите за импортиране и експортиране на ES6, елегантен и поддържан подход, който ни позволява да държим нещата разделени и достъпни само когато имаме нужда от това.

Отчетите за внос и износ

Ключовата дума за износ се използва, когато искаме да направим нещо достъпно някъде, а импортирането се използва за достъп до това, което е направил експорт.

Правилото на палеца е, за да импортирате нещо, първо трябва да го експортирате.

И какво всъщност можем да изнасяме?

  • Променлива
  • Обект буквален
  • Клас
  • Функция
  • ++

За да опростим примера, както е показано по-горе, можем да увием всички скриптове един файл.

След това просто заредете скрипта на app.js в нашия index.html. Но първо, за да го накараме да работи, трябва да използваме type = "module" (source), за да можем да използваме импортирането и експортирането за работа с модули.

Както можете да видите, index.html сега е отговорен за един скрипт, което улеснява поддръжката и мащаба. Накратко, скриптът на app.js става нашата входна точка, която можем да използваме за зареждане на нашето приложение.

Забележка: Не бих препоръчал всички скриптове да се зареждат в един файл, като app.js, с изключение на тези, които го изискват.

Сега, когато видяхме как можем да използваме извлеченията за импортиране и експортиране, нека да видим как работи при работа с модули на практика.

3. Как работят ES6 модулите

Каква е разликата между модул и компонент? Модулът е съвкупност от малки независими единици (компоненти), които можем да използваме повторно в нашето приложение.

Каква е целта?

  • Капсулирайте поведението
  • Лесна за работа
  • Лесен за поддръжка
  • Лесен за мащабиране

Да, това улеснява развитието!

И така, какво всъщност е компонент?

Компонентът може да бъде променлива, функция, клас и т.н. С други думи, всичко, което може да бъде експортирано от оператора за износ, е компонент (или можете да го наречете блок, единица и т.н.).

Какво е компонент

И така, какво всъщност представлява модул?

Както споменахме, модул е ​​съвкупност от компоненти. Ако имаме множество компоненти, които комуникират или просто трябва да бъдат показани заедно, за да образуват интегрирано цяло, тогава най-вероятно се нуждаете от модул.

Какво е модул

Предизвикателство е да направим всичко за многократна употреба

Главен инженер с над 30-годишен опит в електротехниката веднъж каза, че не можем да очакваме всичко да се използва повторно поради време, разходи и не всичко е предназначено да бъде използвано повторно. По-добре е да се използва повторно до известна степен, отколкото да очаквате нещата да бъдат използвани повторно 100%.

По принцип това означава, че не е нужно да правим всичко за многократна употреба в приложението. Някои неща са просто предназначени да бъдат използвани веднъж. Правилото на палеца е, че ако имате нужда от нещо повече от два пъти, тогава може би е добра идея да създадете модул или компонент.

Отначало може да звучи лесно да се направи нещо за многократна употреба, но не забравяйте, че е необходимо да извадите компонента от средата си и да очаквате да работи в друга. Но често пъти се налага да модифицираме части от него, за да го направим напълно използваем и преди да го знаете, сте създали два нови компонента.

Антоан, написа статия, описваща 3 основни правила за създаване на JS компоненти за многократна употреба, която се препоръчва да се прочете. Когато представи VueJS на своя екип, опитен колега казва:

Това е чудесно на теория, но според мен тези фантастични неща за многократна употреба никога не се използват повторно.

Идеята е, че не всичко трябва да се използва повторно, като бутони, полета за въвеждане и квадратчета и т.н. Цялата работа за правенето на нещо за многократна употреба изисква ресурси и време и често стигаме до сценарии на прекомерно мислене, които никога не биха възникнали.

Главният изпълнителен директор на Stack Overflow Джоел Сполски казва:

50% добро решение, което хората всъщност имат, решава повече проблеми и оцелява по-дълго от 99% решение, което никой няма, защото е във вашата лаборатория, където безкрайно полирате проклетото нещо. Доставка е функция. Наистина важна характеристика. Вашият продукт трябва да го има.

4. Нека изградим табло с модули

Сега, когато имаме основно разбиране за това как работят модулите, нека да видим практически пример, с който най-вероятно ще се сблъскате, когато работите с JS рамки. Ще създадем обикновено табло, следвайки архитектурен дизайн, състоящ се от оформления и компоненти.

Кодът за примера можете да намерите тук.

Стъпка 1 - Проектирайте това, което ви трябва

В повечето случаи разработчиците ще скочат директно в кода. Дизайнът обаче е важна част от програмирането и може да ви спести много време и главоболие. Не забравяйте, че дизайнът не трябва да е перфектен, а нещо, което ви води в правилната посока.

Това е, което се нуждаем въз основа на архитектурния дизайн.

  • Компоненти: users.js, user-profile.js и issues.js
  • Оформления: header.js и sidebar.js
  • Табло за управление: dashboard.js

Всички компоненти и оформления ще бъдат заредени в dashboard.js и след това ще зареждаме dashboard.js в index.js.

Архитектурен дизайн на нашето табло

Така че защо имаме папка с оформления и компоненти?

Оформлението е нещо, от което се нуждаем веднъж, например статичен шаблон. Съдържанието вътре в таблото за управление може да се промени, но страничната лента и заглавката ще останат същите (и това са онова, което е известно като оформление). Оформлението може да бъде или страница за грешка, долен колонтитул, страница със състояние и т.н.

Папката с компоненти е за общи компоненти, които най-вероятно ще използваме повече от веднъж.

Важно е да имате стабилна основна структура при работа с модули. С цел ефективно мащабиране, папките трябва да имат разумни имена, които улесняват намирането на неща и отстраняване на грешки.

По-късно ще ви покажа как да създадете динамичен интерфейс, който изисква да има място в папката за необходимите ни компоненти и оформления.

Стъпка 2 - Настройка на структурата на папките

Както споменахме, имаме 3 основни папки: табло за управление, компоненти и оформления.

- табло
- компоненти
- оформления
index.html
index.js (входна точка)

И във всеки файл вътре в папката експортираме клас.

- табло
    dashboard.js
- компоненти
    issues.js
    потребителски profile.js
    users.js
- оформления
    header.js
    sidebar.js
index.html
index.js (входна точка)

Стъпка 3 - Изпълнение

Структурата на папките е зададена, така че следващото нещо, което трябва да направите, е да създадете компонента (клас) във всеки файл и след това да го експортирате. Конвенцията за кода е същата за останалите файлове: всеки компонент е просто клас и метод, който конзолира „x компонент е зареден“, където x е името на компонента, за да покаже, че компонентът е зареден.

Нека създадем потребителски клас и след това да го експортираме, както е показано по-долу.

Забележете, ние имаме различни опции, когато се занимаваме с декларацията за износ. Така че идеята е, че можете да експортирате отделни компоненти, или колекция от компоненти. Например, ако експортираме класа, можем да получим достъп до декларираните методи, като създадем нов екземпляр от класа.

Добре, така че ако погледнете архитектурната схема в стъпка 1, ще забележите, че компонентът на потребителския профил е капсулиран от оформлението на заглавката. Това означава, че когато зареждаме оформлението на заглавката, той ще зареди и компонента на потребителския профил.

Сега, когато всеки компонент и оформление има експортиран клас, след това го импортираме в нашия файл на таблото така:

За да разберем какво наистина се случва във файла на таблото за управление, трябва да прегледаме чертежа в стъпка 1. Накратко, тъй като всеки компонент е клас, трябва да създадем нов екземпляр и след това да го присвоим на обект. След това използваме обекта, за да изпълним методите, както са показани в метод loadDashboard ().

Понастоящем приложението не извежда нищо, защото не сме изпълнили метода loadDashboard (). За да работи, трябва да импортираме модула на таблото във файл index.js по този начин:

И тогава конзолата извежда:

ES6 компоненти са заредени

Както е показано, всичко работи и компонентите се зареждат успешно. Можем също да продължим и да създадем два екземпляра и след това да направим нещо подобно:

Кой изход е същият, както е показано по-горе, но тъй като ние трябва да нови случаи, получаваме резултатите два пъти.

Два уникални екземпляра на таблото за управление

По принцип това ни позволява лесно да поддържаме и използваме отново модула във необходимите файлове, без да пречим на други модули. Просто създаваме нов екземпляр, който капсулира компонентите.

Въпреки това, както беше споменато по-горе, целта беше да се обхване динамиката на това как можем да работим с модули и компоненти, използвайки отчетите за импортиране и експортиране.

В повечето случаи при работа с JS рамки обикновено имаме маршрут, който може да промени съдържанието на таблото за управление. В момента всичко, като оформления, се зарежда всеки път, когато извикваме метода loadDashboard (), което не е идеален подход.

5. Техники за оптимизация за пример на таблото

Сега, когато имаме основно разбиране за това как работят модулите, подходът не е наистина мащабируем или интуитивен, когато имаме работа с големи приложения, които се състоят от много компоненти.

Нуждаем се от нещо, което е известно като динамичен интерфейс. Тя ни позволява да създадем колекция от необходимите ни компоненти и лесно да имаме достъп до нея. Ако използвате Visual Studio Code, IntelliSense ви показва кои компоненти са налични и кои вече сте използвали. Това означава, че не е необходимо да отваряте папката / файла ръчно, за да видите кои компоненти са били експортирани.

Така че, ако имаме модул с двадесет компонента, не искаме да импортираме всеки компонент един ред след друг. Ние просто искаме да получим това, от което се нуждаем, и това е всичко. Ако сте работили с пространства от имена на езици като C #, PHP, C ++ или Java, ще забележите, че тази концепция е подобна по своята същност.

Ето какво искаме да постигнем:

Както е показано, имаме по-малко редове от код и го направихме декларативен, без да губим контекста. Нека да видим какви промени сме направили.

Създайте динамичен интерфейс (известен също като бъчви)

Динамичният интерфейс ни позволява да създадем колекция от неща, от които се нуждаем. Това е като създаване на кутия с инструменти с любимите ни инструменти. Едно нещо, което е важно да се спомене, е, че динамичен интерфейс не трябва да се добавя във всяка отделна папка, а към папки, които се състоят от много компоненти.

Те значително опростяват вноса и ги правят да изглеждат по-ясни. Просто не искаме да имаме прекалено много файлове с барел, тъй като това е твърде продуктивно и обикновено води до проблеми с кръговата зависимост, които понякога могат да бъдат доста трудни за разрешаване.
- Адриан Фачу

За да създадем динамичен интерфейс, създаваме файл с име index.js, който се намира в корена на всяка папка, за да експортираме отново подмножество от файлове или компоненти, от които се нуждаем. Същата концепция работи и в TypeScript, просто променяте типа от .js на .ts като index.ts.

Index.js е първият файл, който се зарежда, когато имаме достъп до пространството на коренната папка - това е същата концепция като index.html, която зарежда нашето HTML съдържание. Това означава, че не трябва изрично да пишем import {компонент} от './components/index.js', а вместо това импортира {компонент} от './components.

Ето как изглежда динамичен интерфейс

Използвайки динамичен интерфейс, ние стигаме до едно по-малко коренно ниво за достъп, а също и по-малко код.

Създайте нов екземпляр по време на изпълнение

Премахнахме четирите инстанции в dashboard.js и вместо това създадохме екземпляр по време на изпълнение, когато всеки компонент се експортира. Ако искате да решите името на обекта, можете да експортирате новото табло за управление по подразбиране () и след това да импортирате dashView без къдравите скоби.

Както е показано, можем директно да извикаме метода, без да е необходимо да създаваме нов екземпляр, а също и да пишем по-малко код. Това обаче е лично предпочитание и можете свободно да решите какъв е практически случай за приложението и изискванията ви.

И накрая, ние зареждаме всички компоненти и оформления с един метод.

заключение

Започнах с намерението само да покажа кратък пример за това как можете да импортирате и експортирате компонент, но след това почувствах необходимостта да споделя всичко, което знам (почти). Надявам се тази статия да ви даде някакъв поглед върху това как да се справяте ефективно с ES6 модулите при изграждането на приложения и нещата, които са важни от гледна точка на разделянето на проблемите (принцип на проектиране).

Вземанията:

  • С ES6 модулите можем лесно да използваме отново, поддържаме, отделяме и капсулираме компоненти от промяна от външно поведение
  • Модулът е колекция от компоненти
  • Компонентът е индивидуален блок
  • Не се опитвайте да правите всичко за многократна употреба, тъй като това изисква време и ресурси, а най-често не го използваме отново
  • Създайте архитектурна схема, преди да се потопите в кода
  • За да направим компонентите достъпни в други файлове, първо трябва да експортираме и след това да импортираме
  • С помощта на index.js (същата концепция за TypeScript index.ts) можем да създадем динамични интерфейси (барели) за бърз достъп до нужните неща с по-малко код и по-малко йерархични пътища
  • Можете да експортирате нов екземпляр по време на изпълнение, като използвате Export let objectName = new ClassName ()

Добрата новина е, че нещата са се променили и се движим към компонентна и многократна парадигма. Въпросът е как можем да използваме не само обикновен JS код, но и HTML елементи по практичен и интуитивен начин. Изглежда, че ES6 модулите, комбинирани с уеб компоненти, могат просто да ни дадат необходимото за изграждане на ефективни и мащабируеми приложения.

Ето няколко статии, които написах за уеб-екосистемата, заедно с лични съвети и трикове за програмиране.

  • Сравнение между Angular и React
  • Хаотичен ум води до хаотичен код
  • Разработчици, които постоянно искат да научат нови неща
  • Научете тези основни уеб концепции
  • Увеличете уменията си с тези важни JavaScript методи
  • Програмирайте по-бързо, като създавате персонализирани bash команди

Можете да ме намерите в Medium, където публикувам седмично. Или можете да ме последвате в Twitter, където публикувам подходящи съвети и трикове за уеб разработка заедно с лични истории за разработчици.

Ако сте харесали тази статия и искате повече подобни, моля, плеснете (❤) и споделете с приятели или колеги, това е добра карма.