Полный цикл в digital

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

По мере роста нашего приложения, мы обычно хотим разделить его на много файлов, так называемых «модулей». Модуль обычно содержит класс или библиотеку с функциями. Долгое время в JavaScript отсутствовал синтаксис модулей на уровне языка. Это не было проблемой, потому что первые скрипты были маленькими и простыми. В модулях не было необходимости.

Со временем скрипты становились всё более и более сложными, поэтому сообщество придумало несколько вариантов организации кода в модули. Появились библиотеки для динамической подгрузки модулей. Например:

  • AMD одна из самых старых модульных систем, изначально реализована библиотекой require.js
  • CommonJS модульная система, созданная для сервера Node.js
  • UMD ещё одна модульная система, предлагается как универсальная, совместима с AMD и CommonJS

Теперь все они постепенно становятся частью истории, хотя их можно найти в старых скриптах. Система модулей на уровне языка появилась в стандарте JavaScript в 2015 году и постепенно эволюционировала, их называют ES модули. Из-за этого разработанные сообществом модули стремительно устарели и ими пользоваться не стоит.

Обратить внимание стоит лишь на модули CommonJS, так как на них изначально работал NodeJS, да и сейчас он работает на них по умолчанию в целях совместимости. Кроме того, часто в инструкциях по подключению различных библиотек вы встретите описание именно CommonJS варианта, а не ES. Поэтому вы должны представлять себе, как переделать код CommonJS на ES.

Есть еще нюанс, хотя модули теперь закреплены в стандарте JavaScript, просто так они не будут работать в браузере. Для этого нужно использовать один из популярных инструментов сборки.

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

Модуль – это просто файл, один скрипт – это один модуль.

Модули могут загружать друг друга и использовать директивы export и import, чтобы обмениваться функциональностью, вызывать функции одного модуля из другого:

  • export отмечает переменные и функции, которые должны быть доступны вне текущего модуля
  • import позволяет импортировать функциональность из других модулей

У нас есть основной файл:

index.html<!DOCTYPE html>
<html lang="ru">
  <head>
    <title>hmarketing.ru</title>
  </head>
  <body>
    <div></div>
    <button>Нажми</button>
  </body>
  <script type="module" src="main.js"></script>
</html>

Файл say.js, экспортирует функцию из другого файла:

say.jsexport function sayHi() {
  let div = document.querySelector("div");
  div.innerHTML = "Модульная функция отработана";
}

Другой файл main.js может импортировать и использовать функцию sayHi():

main.jsimport { sayHi } from "./say.js";
let button = document.querySelector("button");
button.addEventListener("click", function () {
  sayHi();
});

Директива import загружает модуль по пути ./say.js относительно текущего файла и записывает экспортированную функцию sayHi.

Основные возможности модулей

Чем отличаются модули от «обычных» скриптов? Есть основные возможности и особенности, работающие как в браузере, так и в серверном JavaScript.

Всегда use strict

В модулях всегда используется режим use strict. Например, присваивание к необъявленной переменной вызовет ошибку:

<script type="module">
a = 5; // ошибка
</script>

Своя область видимости переменных

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

В браузере также существует независимая область видимости для каждого скрипта <script type="module">:

<script type="module">
// Переменная доступна только в этом модуле
let user = "John";
</script>
<script type="module">
alert(user); // Error: user is not defined
</script>

Если нам нужно сделать глобальную переменную уровня всей страницы, можно явно присвоить её объекту window, тогда получить значение переменной можно обратившись к window.user. Но это должно быть исключением, требующим веской причины.

Код в модуле выполняется только один раз при импорте

Если один и тот же модуль используется в нескольких местах, то его код выполнится только один раз, после чего экспортируемая функциональность передаётся всем импортёрам.

import.meta

Объект import.meta содержит информацию о текущем модуле. Содержимое зависит от окружения. В браузере он содержит ссылку на скрипт или ссылку на текущую веб-страницу, если модуль встроен в HTML:

<script type="module">
alert(import.meta.url); // ссылка на html страницу для встроенного скрипта
</script>

В модуле «this» не определён

Это незначительная особенность, но для полноты картины нам нужно упомянуть об этом. В модуле на верхнем уровне this не определён (undefined). Сравним с не-модульными скриптами, там this – глобальный объект:

<script>
alert(this); // window
</script>
<script type="module">
alert(this); // undefined
</script>
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг