Скрипты модулей ES: type=module
Загружайте JavaScript как модули ES с помощью type=module
«Скрипты модулей ES: type=module» — бесплатный урок HTML Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения HTML Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс HTML Academy содержит 4 уроков всего.
Что такое модули ES
ES-модуль — это файл JavaScript, в котором используются объявления import и export. У модулей есть собственная область видимости (без загрязнения глобальной области), строгий режим по умолчанию и явно указанные зависимости — это решает проблемы с порядком тегов скриптов, которые накапливались десятилетиями.
Тег скрипта модуля
<script type="module" src="app.js"> сообщает браузеру, что файл является модулем. Браузер разбирает импорты, параллельно загружает зависимости и выполняет точку входа только после загрузки и компиляции всего графа зависимостей.
<script type="module" src="app.js"></script>Модули выполняются отложенно
Скрипты модулей ведут себя так, как будто у них задан defer: они загружаются параллельно с разбором HTML и выполняются после разбора в порядке объявления. Вы можете разместить <script type="module"> где угодно (даже в <head>), не блокируя страницу.
Импорты используют спецификаторы
В объявлении импорта используется спецификатор — относительный URL (./utils.js), абсолютный URL (https://cdn.example.com/lib.js) или короткое имя (lodash). Для коротких имён требуется карта импорта (о ней рассказывается далее), поскольку браузер не знает, какому файлу они соответствуют.
// app.js
import { sum } from "./utils.js";
import { render } from "https://esm.sh/preact";
console.log(sum(1, 2));Расширения файлов обязательны
Браузеры не добавляют автоматически .js к спецификаторам импорта. import "./utils" завершается ошибкой, а import "./utils.js" работает. Сборщики и Node могут быть более снисходительными, но браузер строг, поэтому явно указывайте расширение.
Требуется CORS
Модули всегда загружаются с использованием CORS, даже если источник тот же. Файлы модулей из другого источника должны передавать подходящий заголовок Access-Control-Allow-Origin, иначе импорт завершится ошибкой. Большинство CDN (esm.sh, jsdelivr, unpkg) сразу правильно настраивают это.
Ожидание на верхнем уровне
Модули поддерживают await на верхнем уровне — обёртка в асинхронную функцию не требуется: const data = await fetch("/api").then(r => r.json()). Потребители модуля ждут завершения ожидания на верхнем уровне, прежде чем начать выполнение.
// data.js
export const config = await fetch("/config.json").then(r => r.json());
// app.js (waits for data.js)
import { config } from "./data.js";
console.log(config);Модули являются синглтонами
Модуль вычисляется ровно один раз за сеанс независимо от того, сколько других модулей его импортирует. Объект экспортов является общим: каждый потребитель видит один и тот же экземпляр. Поэтому модули удобно использовать для совместного доступа к единственным экземплярам, например к объекту конфигурации или хранилищу состояния.
Встроенные модули
Модули можно также писать непосредственно в документе: <script type="module">import x from "./y.js"; ...</script>. Это удобно для начального кода или экспериментов, хотя внешние файлы проще отлаживать и кэшировать.
nomodule для резервного варианта
Сочетайте <script type="module"> с <script nomodule src="legacy.js">. Современные браузеры выполняют модуль и игнорируют скрипт nomodule; устаревшие браузеры выполняют скрипт nomodule и игнорируют модуль. Такой подход используют при переходе на приложения, полностью построенные на ESM.
Ошибки и сбои импорта
Если импорт завершается ошибкой (404, CORS, синтаксическая ошибка), возникает исключение и выполнение всего графа модулей прекращается. Используйте панель сети, чтобы найти неудачные запросы модулей, а в консоли прочитайте фактическое сообщение об ошибке импорта.
Проверка знаний
Почему скрипты модулей ведут себя так, как будто для них задано отложенное выполнение, даже если Вы не указали его явно?
Итоги
<script type="module"> загружает ES-модули — файлы в строгом режиме с объявлениями import/export, которые формируют граф зависимостей. Модули по умолчанию выполняются отложенно, требуют явно указанных расширений файлов, загружаются с CORS, вычисляются как единственные экземпляры и поддерживают ожидание на верхнем уровне. Используйте nomodule для резервного варианта в устаревших браузерах и проверяйте отсутствие расширений файлов, когда импорты завершаются ошибкой без очевидной причины.
Часто задаваемые вопросы
Урок «Скрипты модулей ES: type=module» бесплатный?
Да — полный текст урока «Скрипты модулей ES: type=module» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс HTML Academy, подпишись на CoddyKit PRO. Курс HTML Academy содержит 4 уроков всего.
Чему я научусь в уроке «Скрипты модулей ES: type=module»?
Загружайте JavaScript как модули ES с помощью type=module Ты практикуешь HTML Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать HTML Academy?
Предыдущий опыт не требуется. HTML Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Скрипты модулей ES: type=module»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке HTML Academy?
Да. Каждый урок HTML Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Скрипты модулей ES: type=module
- Карты импорта: importmap
- Динамический import() в модулях
- Основы федерации модулей