Модули: введение #
Модуль — отдельный файл JavaScript со своей областью видимости. Другие файлы подключают его через import и получают только то, что модуль явно экспортировал. Так код делят на независимые части без глобальных конфликтов имён.
Зачем модули #
| Без модулей | С модулями |
|---|---|
Всё в глобальной области window | Переменные по умолчанию локальны для файла |
Порядок <script> критичен | Зависимости описаны в import |
| Сложно переиспользовать в проекте | Файл = единица публикации API |
Риск коллизий utils, config | Имена экспорта контролируются явно |
// cart.js — только экспорт виден снаружи
const taxRate = 0.2
export function lineTotal(price, qty) {
return price * qty * (1 + taxRate)
}
taxRate снаружи cart.js недоступен — не засоряет глобальную область.
ES-модули (ESM) #
Современный стандарт — ECMAScript modules (ключевые слова import / export). Старые форматы (CommonJS require в Node, IIFE-бандлы) встречаются в legacy-проектах; в JSFlow опираемся на ESM.
Особенности ESM:
- Строгий режим включён всегда (
"use strict"не нужен). - Импорты и экспорты разрешены только на верхнем уровне файла (не внутри
ifна верхнем уровне — для ветвления естьimport()). - Модули defer: в браузере выполняются после разбора HTML, в предсказуемом порядке графа зависимостей.
- Повторный импорт одного URL кэшируется — модуль выполняется один раз.
type=“module” в браузере #
Подключение ES-модуля в HTML:
<script type="module" src="/js/checkout/main.js"></script>
Отличия от обычного <script>:
| Атрибут / поведение | type="module" | классический script |
|---|---|---|
| defer | да, по умолчанию | только с атрибутом defer |
import / export | да | синтаксическая ошибка |
| область | модульная | глобальная (если не IIFE) |
| CORS | да, для файлов с другого origin | зависит от сценария |
Точка входа приложения — один main.js, который импортирует остальное:
// main.js
import { initCheckout } from './checkout.js'
import { bindPlaylistUI } from './playlist-panel.js'
initCheckout()
bindPlaylistUI()
Пути в import должны быть относительными (./, ../) или полными URL; голое имя 'lodash' не резолвится браузером без import map (отдельная тема).
Модуль vs обычный скрипт #
<!-- глобальный побочный эффект -->
<script src="/legacy/analytics.js"></script>
<!-- модульная точка входа -->
<script type="module" src="/js/app.js"></script>
Сторонние библиотеки без ESM часто подключают бандлером (Vite, webpack) или через CDN с готовым export.
Node.js #
В Node файлы с расширением .mjs или "type": "module" в package.json трактуются как ESM. Синтаксис import/export тот же; отличия в резолве путей и взаимодействии с CommonJS — см. документацию Node для смешанных проектов.
Итог #
- Модуль инкапсулирует код и отдаёт наружу только
export. - ESM — стандарт для новых браузерных и многих Node-проектов.
- В HTML модули подключают через
<script type="module">. - Зависимости между файлами задаются явно, а не порядком тегов
<script>.