Module not found: Error: Can't resolve 'lodash' in '/app/src' / Can't resolve 'fs'
#Как Webpack ищет модули
Для импорта import x from 'name' Webpack ищет пакет в node_modules (по цепочке каталогов вверх), для относительных путей (./file) — файл с расширениями из resolve.extensions. Сообщение «Can't resolve» означает, что модуль не найден по всем правилам. Частые причины: пакет не установлен или удалён, опечатка в имени или пути, разный регистр (на macOS/Windows работает, на Linux нет), отсутствует расширение в resolve.extensions, неверный alias, пакет в devDependencies не установился при npm ci --omit=dev, модуль Node.js (fs, path) в браузерной сборке Webpack 5 без полифила.
#Типичные причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Пакет не установленЗабыли npm install. | Can't resolve 'name'. | npm install name. |
| Опечатка в путиНеверное имя файла. | Can't resolve './Header'. | Исправьте путь. |
| Регистр имёнHeader.js против header.js. | Работает локально на Mac, падает на CI. | Совпадение регистра. |
| Нет расширения в resolve.extensions.tsx/.jsx. | Файл не находится. | Добавьте расширение. |
| Неверный aliasПуть изменён. | Can't resolve '@/...'. | Исправьте alias. |
| Модуль Node в браузерной сборкеfs, path, crypto. | Webpack 5 не полифилит. | Добавьте fallback или не используйте. |
#Порядок
- Прочитайте сообщение: какой модуль и из какого каталогаОткройте терминал в корневой папке проекта (VS Code: «Терминал» → «Создать терминал»). Прочтите полный вывод Webpack: после
Can't resolveуказано требуемое имя, а строкаin ...показывает каталог исходного файла. Запишите оба пути. Импорт./Header— относительный файл; импортreact— пакет. Их проверяют разными способами, не устанавливайте пакет по имени файла. - Проверьте, установлен ли пакет: npm ls имяЕсли в ошибке указан пакет без
./или../, в корне проекта выполнитеnpm ls имя_пакета, заменив имя реальным названием из сообщения, напримерnpm ls lodash. Если пакет отображается как(empty)илиmissing, проверьте разделdependencies/devDependenciesвpackage.json. Для локального импорта./Headerэту проверку пропустите и переходите к проверке пути. - Установите пакет: npm install имяТолько если отсутствует сторонний пакет, в каталоге с
package.jsonвыполнитеnpm install имя_пакета, подставив точное имя из ошибки; если он нужен исключительно для сборки, используйтеnpm install --save-dev имя_пакета. Убедитесь, что команда завершилась безnpm ERR!и что пакет появился в зависимостях. Если ошибка вызвана неправильным названием импорта, исправьте строкуimport, а не устанавливайте случайные пакеты. - Проверьте путь и регистр файловДля импорта с
./или../откройте указанный в ошибке исходный файл, найдите строкуimport/requireи сравните её с реальным путём на диске. Проверьте количество../, расширение и регистр:Header.tsxиheader.tsx— разные имена в Linux. Используйте поиск файлов в редакторе илиgit ls-files; исправьте имя и повторите сборку. - Проверьте resolve.extensions и resolve.alias в конфигурацииЕсли файл и пакет существуют, откройте
webpack.config.jsи найдите секциюresolve. Сверьтеaliasс действительными каталогами; для относительных каталогов в конфигурации обычно используютpath.resolve(__dirname, 'src'). Проверьте, входит ли используемое расширение вresolve.extensions, либо явно напишите расширение в импорте. После правки запуститеnpm run buildили штатный сценарий изpackage.json. - Для Webpack 5 и модулей Node настройте resolve.fallbackЭтот шаг нужен только если Webpack 5 собирает код ДЛЯ БРАУЗЕРА, а сторонняя библиотека импортирует встроенный модуль Node (
crypto,stream,pathи др.). Webpack 5 больше не подставляет браузерные замены автоматически. Проверьте, предусмотрена ли у библиотеки версия для браузера. Лишь если подходящая замена действительно нужна, установите совместимый пакет и задайтеresolve.fallbackпо его документации; серверный модуль нельзя автоматически считать доступным в браузере. - Удалите node_modules и lock-файл при конфликте версий, установите зановоЕсли зависимости установлены, но ошибка появилась после смены ветки или версии Node, сначала сохраните
package-lock.jsonи выполнитеnpm ciиз корня проекта — команда устанавливает строго по существующему файлу блокировки и пересоздаётnode_modules. Она удалит текущийnode_modules, поэтому сохраните любые вручную созданные в нём файлы. Не удаляйтеpackage-lock.json: это меняет закреплённые версии и затрудняет воспроизведение проблемы. - Очистите кэш WebpackОчистку выполняйте только после исправления путей и проверки зависимостей. Для проекта, использующего файловый кэш Webpack, остановите сборку, затем удалите конкретный каталог кэша (например,
node_modules/.cache/webpack, если он существует). Не стирайте все скрытые каталоги или системные файлы. Запустите сборку заново; если ошибка не изменилась, причина, вероятно, не в кэше. - Проверьте, что сборка запускается из нужного каталогаПроверьте текущую папку командой
pwd(Linux/macOS) илиcd(Windows), затем убедитесь, что рядом естьpackage.json. Откройтеpackage.json, найдитеscriptsи запустите указанный сценарий, обычноnpm run build. Если сборка прошла, проверьте выходной каталог и приложение; если нет — сохраните первые строки исходной ошибки, а не только финальноеModule not found. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Монорепозитории
В монорепозиториях (npm workspaces, pnpm, yarn) зависимости поднимаются в корень. Запускайте установку из корня и проверьте resolve.modules. Для pnpm используйте resolve.symlinks и настройте pnpm install без изоляции только если необходимо. При ошибке «в пакете нет подпути» проверьте поле exports в package.json зависимости.