CommonJS (require)

Тема дорожной карты · Node.js

CommonJS — исходная система модулей среды выполнения JavaScript Node.js: она использует require() для синхронной загрузки модулей и module.exports или exports для предоставления публичного API модуля. При вызове require() Node.js разрешает путь модуля, выполняет файл, кэширует результат в require.cache и возвращает экспортированное значение — последующие вызовы require() с тем же путём возвращают кэшированный модуль без повторного выполнения. Алгоритм разрешения модулей CommonJS следует определённой последовательности: Node.js сначала ищет точное совпадение файла, затем добавляет расширения .js, .json и .node, и наконец ищет файл index.js, что делает поведение предсказуемым для авторов серверных пакетов. Поле "main" в каждом package.json указывает на точку входа CommonJS для npm-пакета, и большинство экосистемы — включая express, lodash и тысячи других пакетов — изначально публиковались в виде модулей CommonJS. Несмотря на то что ECMAScript Modules (ESM) с синтаксисом import/export теперь поддерживаются нативно в Node.js, require() CommonJS по-прежнему широко используется в существующих серверных кодовых базах и инструментарии.

Как это работает

CommonJS (require) имеет два формата: CommonJS (legacy дефолт, require/module.exports, синхронный) и ES Modules (import/export, асинхронный, browser-compatible). Файлы резолвятся загрузчиком модулей: относительные пути → обход node_modules → встроенные. "type": "module" в package.json переключает дефолт для .js; расширения .mjs и .cjs форсируют формат. Conditional exports (exports в package.json) позволяют пакету поставлять оба формата.

Когда применять

Для новых проектов ESM — это стандарт JS, поддерживает top-level await, ожидается бандлерами/тулингом. CommonJS — только когда legacy-зависимости требуют или цена миграции запретительная. import("./mod.js") — для динамической / условной загрузки. Бандлер (esbuild, tsup) — только если публикуете пакет в обоих форматах; backend-сервисы обычно гоняют исходник.

Типичные ошибки

Ловушки CommonJS (require): пропущенное расширение .js в ESM-импортах (тихо ломается); циклические импорты (A → B → A — одна сторона получает partial export); случайный бандл CommonJS-only пакета в ESM-проект (interop болезненный); __dirname/__filename отсутствуют в ESM (используйте import.meta.url). Прочтите доку Node.js ESM перед битвой с "unexpected token".

Связанные понятия

Полезные ресурсы