Модули JavaScript

Это руководство содержит всю необходимую информацию для начала работы с модулями JavaScript.

Модули: история вопроса

Сначала программы на JavaScript были небольшими — в прежние времена они использовались для изолированных задач, добавляя при необходимости немного интерактивности веб-страницам, так что большие скрипты в основном не требовались. Прошло несколько лет, и вот мы уже видим полномасштабные приложения, работающие в браузерах и содержащие массу кода на JavaScript; кроме того, язык стал использоваться и в других контекстах (например, Node.js).

Таким образом, в последние годы появились причины на то, чтобы подумать о механизмах деления программ на JavaScript на отдельные модули, которые можно импортировать по мере необходимости. Node.js включал такую возможность уже давно, кроме того, некоторые библиотеки и фреймворки JavaScript разрешали использование модулей (например, CommonJS и основанные на AMD системы модулей типа RequireJS, а позднее также Webpack и Babel).

К счастью, современные браузеры стали сами поддерживать функциональность модулей, о чем и рассказывает эта статья. Этому можно только порадоваться — браузеры могут оптимизировать загрузку модулей, что было бы гораздо эффективнее использования библиотеки, и взять на себя обработку на стороне клиента и прочие накладные расходы.

Встроенная обработка модулей JavaScript связана с инструкциями import и export, их поддержка браузерами показана в следующих таблицах.

Совместимость с браузерами

Пример использования модулей

Для того, чтобы продемонстрировать использование модулей, мы создали простой набор примеров, который вы можете найти на GitHub. В этих примерах мы создаём элемент на веб-странице и затем рисуем различные фигуры на нём (и выводим информацию об этом).

Примеры довольно тривиальны, но они намеренно сделаны простыми для ясной демонстрации модулей.

Примечание: Если вы хотите скачать примеры и запустить их локально, вам нужно будет запустить их через локальный веб-сервер.

Базовая структура примера

В первом примере (см. директорию basic-modules) у нас следующая структура файлов:

index.html
main.js
modules/
    canvas.js
    square.js

Примечание: Все примеры в этом руководстве в основном имеют одинаковую структуру.

Давайте разберём два модуля из директории modules:

  • canvas.js — содержит функции, связанные с настройкой canvas:

    • create() — создаёт холст заданной ширины width и высоты height внутри
      -обертки с указанным id и помещённой в родителя parent. Результатом выполнения функции будет объект, содержащий 2D-контекст холста и id обертки.
    • createReportList() — создаёт неупорядоченный список, добавленный внутри указанного элемента-обёртки, который можно использовать для вывода данных отчёта. Возвращает id списка.
  • square.js — содержит:

    • name — переменная со строковым значением 'square'.
    • draw() — функция, рисующая квадрат на указанном холсте с заданными размером, положением и цветом. Возвращает объект, содержащий размер, положение и цвет квадрата.
    • reportArea() — функция, которая выводит посчитанную площадь квадрата в указанный список отчета.
    • reportPerimeter() — функция, которая выводи посчитанный периметр квадрата в указанный список отчета.

Взгляд со стороны — .mjs против .js

В этой статье мы используем расширение .js для файлов наших модулей, но в других источниках вы можете встретить расширение .mjs. Например, в документации движка V8 используется .mjs. Причины следующие:

  • Это полезно для ясности, то есть дает понять, какие файлы являются модулями, а какие — обычными JavaScript-файлами.
  • Это гарантирует, что файлы вашего модуля будут проанализированы как модуль средами выполнения, такими как Node.js, и инструментами сборки, такими как Babel.

Тем не менее, мы решили продолжать использовать .js, по крайней мере на данным момент. Чтобы модули корректно работали в браузере, вам нужно убедиться, что ваш сервер отдаёт их с заголовком Content-Type, который содержит JavaScript MIME type такой как text/javascript. В противном случае вы получете ошибку проверки MIME type — "The server responded with a non-JavaScript MIME type", и браузер не сможет запустить ваш JavaScript. Большинство серверов уже имеют правильный тип для .js-файлов, но ещё не имеют нужного MIME type для .mjs-файлов. Серверы, которые уже отдают .mjs файлы корректно, включают в себя GitHub Pagesи http-сервер для Node.js.

Это нормально, если вы уже используете такую среду или ещё нет, но знаете, что делать, и имеете нужные доступы (то есть вы можете настроить свой сервер, чтобы он устанавливал корректный Content-Type-заголовок для .mjs-файлов). Однако это может вызвать путаницу, если вы не контролируете сервер, с которого отдаются файлы, или публикуете файлы для общего пользования, как мы здесь.

В целях обучения и переносимости на разные платформы мы решили остановится на .js.

Если вы действительно видите ценность и ясность использования .mjs для модулей по сравнению с использованием .js для обычных JavaScript-файлов, но не хотите столкнуться с проблемой описанной выше, вы должны всегда использовать .mjs во время разработки и конвертировать их в .js во время сборки.

Также стоит отметить, что:

  • Некоторые инструменты могут никогда не добавить поддержку .mjs, например, TypeScript.

Вы также можете встроить скрипт модуля непосредственно в HTML-файл, поместив JavaScript-код внутрь