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

Для начала ответим на вопрос что такое 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 проекта, что облегчает работу фронт-энд веб разработчиков в команде, а значит ускоряет и удешевляет создание сайтов и веб приложений.

Добавить комментарий

Ваш адрес email не будет опубликован.