Разрешение модулей
Тема дорожной карты · Node.js
Разрешение модулей — это алгоритм, используемый Node.js для поиска и загрузки модуля при вызове require() или import в файле JavaScript или TypeScript. Node.js сначала проверяет, является ли указанный путь встроенным модулем вроде fs или path, затем ищет в директориях node_modules, поднимаясь вверх по файловой системе, и наконец применяет поля exports и main, определённые в package.json пакета. Понимание разрешения модулей необходимо для серверной разработки, поскольку неправильно настроенные пути являются одной из наиболее частых причин ошибок MODULE_NOT_FOUND в продакшн-приложениях Node.js. TypeScript добавляет свой уровень разрешения модулей, управляемый полями tsconfig.json, такими как moduleResolution, paths и baseUrl, которые должны соответствовать алгоритму разрешения среды выполнения Node.js во избежание расхождений между поведением при компиляции и во время выполнения.
Как это работает
Разрешение модулей имеет два формата: 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-сервисы обычно гоняют исходник.
Типичные ошибки
Ловушки Разрешение модулей: пропущенное расширение .js в ESM-импортах (тихо ломается); циклические импорты (A → B → A — одна сторона получает partial export); случайный бандл CommonJS-only пакета в ESM-проект (interop болезненный); __dirname/__filename отсутствуют в ESM (используйте import.meta.url). Прочтите доку Node.js ESM перед битвой с "unexpected token".