Що таке модуль

Для початку відповімо на запитання, що таке JavaScript модулі і навіщо вони потрібні. Для цього, трохи зануримося в темні часи, коли розробка сайтів, які мають якусь не складну динамічну функціональність на стороні клієнта, була складним завданням, і почнемо з того, що розглянемо передумови виникнення модулів.

До виникнення модулів і стандарту ES6 JavaScript видимість змінних обмежувалася тільки функціями. Якщо змінна була оголошена поза функцією, вона глобальна і доступна в будь-якому місці на сторінці і в будь-якому файлі зі скриптами. У великих сайтах або програмах це породжувало великі незручності та проблеми, так як у різних файлах імена змінних могли збігатися, що призводило до помилок. Ця проблема вирішувалася за допомогою так званих функцій, що негайно викликаються – Immediately Invoked Function Expression (IIFE).

Весь вміст js-файлу містився в таку конструкцію:

(function() {
    //весь вміст JavaScript файлу
})();

Все всередині цієї функції негайно виконується, тобто те саме, що без неї, але при цьому всі змінні оголошені всередині цієї функції та їх область видимості обмежена нею. Таким чином Front-End розробники могли займатися різними частинами програми та не заважати один одному.

Слід згадати, що всередині команди, програмісти цілком могли домовитися про використання певних просторів імен, але вони також могли використовувати і сторонні скрипти, тому використання IIFE був єдиним робочим варіантом для структурування JavaScript додатка, але при цьому виникали труднощі з передачею даних і з цього модуля псевдо. Тобто JavaScript розробники потребували кращого інструменту, який був принесений стандартом ES6 у 2015 році.

JavaScript модуль це механізм структурування та групування коду, який дозволяє інкапсулювати код в один файл та визначати які його частини будуть видні навколишньому середовищу. Для цього використовуються два ключові слова Import та Export. Export дозволяє створювати модуль та експортувати певний функціонал, Import, відповідно, дозволяє цей функціонал використовувати поза модулем.

Характеристики модулів

Модуль це синглтон (singleton), він єдиний у своєму роді, тобто якщо ми підключаємо один і той же модуль, ми будемо використовувати не копії цього модуля, а ті самі дані. Тобто, якщо в якомусь місці щось зміниться в ньому, ці зміни будуть у всіх імпортах.

Я вже згадував, але варто акцентувати на цьому, один модуль – це один файл, не можна розмістити кілька модулів в одному файлі.

Створення модулів

Створення модуля JavaScript, як я відзначав раніше, передбачає використання ключового слова Export. Воно дозволяє веб розробнику розкривати поза модулем порції функціоналу. Це робиться трьома різними способами: іменний експорт та експорт за замовчуванням.

Іменний експорт

Іменний експорт дозволяє відкривати доступ до чогось, що має ім’я. Це може бути, наприклад, функція або просто змінна. Знаючи це ім’я, ми можемо потім його використовувати для імпорту в іншому місці.

Базовий код для експорту у файлі модуля someFunctions.js:

export function firstFunction() {
    //якийсь js код
}

export function secondFunction() {
    //якийсь js код другої функції
}

У прикладі вище не обов’язково щоразу писати export перед тим, що хочемо експортувати, якщо в модулі багато елементів для експорту. Можна все експортувати одним махом:

export {firstFunction, secondFunction};

У цьому випадку можна також перейменувати щось для експорту, наприклад, так:

export {firstFunction, secondFunction as newFunction};

Потім ми можемо імпортувати та використовувати ці функції в іншому JavaScript файлі таким чином:

import {firstFunction, secondFunction} from './someFunctions.js';

Або у разі перейменування:

import {firstFunction, newFunction} from './someFunctions.js';

Тут особливим є те, що необхідно знати імена елементів, які експортуються/імпортуються.

Експорт за замовчуванням

Цей спосіб дозволяє не прив’язуватися до певних імен, експортувати і потім імпортувати функціонал у своїй не знаючи, як і називається у вихідному модулі.

Для створення стандартного експорту потрібно використовувати ключове слово default. Наприклад:

export default function firstFunction() {
    //якийсь js код
}

Інший варіант експорту за замовчуванням:

export {firstFunction as default};

У такому випадку для імпорту не обов’язково знати ім’я цієї функції, і можна використовувати будь-яке інше ім’я, яке може не співпадати з оригінальним:

import anyFunction from './someFunctions.js';

Зверніть увагу, що при використанні іменного імпорту не використовуються фігурні дужки. Також слід зазначити, що експортувати за замовчуванням можна тільки одну сутність на один модуль, але при цьому можна комбінувати його з іменним експортом. Тобто, ключове слово default можна використовувати лише один раз, але одночасно можна експортувати й інші речі, використовуючи іменний експорт:

export {firstFunction as default, secondFunction};

Використання модулів

Модулі із стандарту ES6 підтримуються всіма сучасними браузерами, навіть Edge. Internet Explorer, звичайно ж, не підтримує їх, але на момент написання статті йому залишилося жити приблизно пів року і Microsoft офіційно перестане його підтримувати. Отже, якщо ви веб-розробник, можете сміливо використовувати модулі у своїй роботі.

Щоб увімкнути та використовувати файл-модуль у HTML сторінку потрібно в тезі скрипт додати атрибут type="module":

<script src="js/app.js" type="module"></script>

Цей атрибут включає можливість використання export/import функціональності в даному файлі.

Файл app.js можна використовувати, щоб об’єднати всі модулі та всю функціональність. Розглянемо усі варіанти імпортів.

Іменний імпорт

import {firstFunction, secondFunction} from './someFunctions.js';

В даному випадку потрібно знати імена сутностей, що експортуються, щоб мати можливість їх імпортувати.

Імпорт за замовчуванням

import anyFunction from './someFunctions.js';

При імпорті за промовчанням не обов’язково знати те, що експортується. Якщо потрібно імпортувати ще щось, потрібно використовувати іменний імпорт або комбінувати в гібридний наступним чином:

import anyFunction, {secondFunction} from './someFunctions.js';

Ще одним варіантом імпорту буде імпорт всього:

import * as func from './someFunctions.js';

І використовувати функції, що імпортуються, як методи об’єкта func: func.firstFunction().

На цьому все. Як бачите, все дуже просто і прямолінійно, але ця простота вносить порядок в організації зрозумілої структури JavaScript проекту, що полегшує роботу фронт-енд веб-розробників у команді, а значить прискорює і здешевлює створення сайтів і веб-додатків.





Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься.