#Что означает ошибка
ERR_MODULE_NOT_FOUND
Error [ERR_MODULE_NOT_FOUND]: Cannot find module в ESM-проектах Node.js возникает, когда импорт не может быть разрешён строгими правилами ES-модулей. В отличие от CommonJS, ESM требует полного расширения файла и не подставляет index.js.
Ошибка часто появляется после перевода проекта на "type": "module".
Проверьте путь, расширение и поле exports пакета.
В ESM нужно указывать расширение файла в import и корректный type в package.json. Проверьте путь и exports пакета.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Нет расширения.js. | Ошибка. | Добавьте. |
| Неверный путьФайл. | Ошибка. | Исправьте. |
| type: modulepackage.json. | Ошибка. | Настройте. |
| Нет пакетаnode_modules. | Ошибка. | npm install. |
#Пошаговое решение
- Добавьте расширение .js в импортыВ терминале проекта выполните исходную команду запуска, например
node app.mjs, и прочитайте полный текст ошибкиERR_MODULE_NOT_FOUND. Скопируйте путь изCannot find module ... imported from ...; он показывает, что именно Node не смог разрешить. Сначала различите относительный импорт./...и имя пакетаreact/другой зависимости. Не начинайте с переустановки всех зависимостей: отсутствие локального файла и отсутствие пакета решаются по-разному. - Проверьте установку пакетаЕсли в ошибке указан относительный путь, откройте файл-источник и найдите строку
import. В стандартном ESM Node для относительного файла укажите расширение: вместо./utilsиспользуйте./utils.js, а вместо./lib—./lib/index.js, если такой файл действительно есть. Учитывайте регистр имени (Utils.jsнеutils.jsв Linux), наличие компиляции TypeScript вdistи относительность к импортирующему файлу. Снова запустите приложение и убедитесь, что ошибка исчезла; если Node теперь сообщает другой путь — исправляйте его отдельно. - Проверьте поле exports пакетаЕсли не найден сторонний пакет, откройте терминал в папке с
package.json, проверьте запись вdependencies/devDependenciesи выполнитеnpm ls имя-пакетазаменив имя на то, что указано в ошибке. Если отсутствует, используйте штатную установку проекта —npm ciпри наличииpackage-lock.json, иначеnpm installсогласно правилам проекта. Проверьте, что вы не запускаете код из другого каталога и пакет установлен именно в нужном рабочем пространстве. Не добавляйте зависимость глобально для локального импорта. - Проверьте type в package.jsonЕсли Node пишет
ERR_PACKAGE_PATH_NOT_EXPORTEDвместоERR_MODULE_NOT_FOUND, это отдельная ошибка: откройтеnode_modules/имя-пакета/package.jsonи изучитеexports, затем используйте публичный путь, указанный в документации пакета. Попытки импортироватьpkg/lib/private.jsнапрямую могут запрещаться самим пакетом, даже когда файл существует. ДляERR_MODULE_NOT_FOUNDсначала устраните реальное отсутствие файла/пакета, а не меняйтеtypeавтоматически. - Используйте import.meta.url вместо __dirnameСверьте в ближайшем
package.jsonполеtypeи расширения.mjs,.js,.cjs, если после исправления пути возникла ошибка модулей.__dirnameиrequireотносятся к CommonJS и не доступны напрямую в обычном ESM; при необходимости используйтеimport.meta.urlилиcreateRequireпо назначению. Для TypeScript сNodeNextпроверьте, что выходная сборка и относительные импорты согласованы; затем повторите запуск и, если ошибка сохранилась, запишите полный путь и версиюnode -v.
#Относительные импорты
Укажите расширение: import { a } from "./utils.js" (даже если исходник TypeScript — пишите .js). Для каталогов указывайте ./dir/index.js явно. Проверьте регистр имён и существование файла. Если проект на TypeScript с "module": "NodeNext", расширения .js обязательны. Запустите исходную команду и прочитайте точный путь Cannot find module ... imported from ...; --trace-warnings не является основным средством диагностики ошибки разрешения модулей.
#Пакеты и exports
Для пакетов проверьте, что они установлены: npm ls имя. Если пакет использует поле exports, можно импортировать только заявленные подпути (import x from "pkg/feature"). Глубокие импорты pkg/lib/file.js блокируются. Для CommonJS-пакетов в ESM используйте import pkg from "pkg" и createRequire: import { createRequire } from "module"; const require = createRequire(import.meta.url);.
#Конфигурация
Проверьте "type": "module" в package.json и расширения файлов .mjs/.cjs. __dirname и require в ESM недоступны: используйте import.meta.url и fileURLToPath. Алиасы путей (@/) в чистом Node не работают — используйте imports в package.json ("#utils/*": "./src/utils/*.js") или сборщик. Для загрузчиков tsx/ts-node ESM: node --import tsx app.ts.
import { createRequire } from "node:module";import { fileURLToPath } from "node:url";// Используется только при необходимости в настоящем ES-модулеconst require = createRequire(import.meta.url);const moduleDir = fileURLToPath(new URL(".", import.meta.url));