Предупреждение UNRESOLVED_IMPORT

Суть предупреждения

UNRESOLVED_IMPORT в Rollup возникает в момент, когда сборщик не может найти модуль, указанный в операторе import. Это означает, что на этапе построения графа зависимостей Rollup обнаруживает ссылку на модуль, который не удаётся разрешить ни через файловую систему, ни через установленные плагины резолва.

Внутренне Rollup строит граф модулей, начиная с входной точки. Каждый import преобразуется в попытку поиска файла. Если ни один резолвер не может сопоставить путь с существующим модулем, фиксируется предупреждение:

(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
Some modules could not be resolved: 
  some-module (imported by src/index.js)

Типовые причины возникновения

Отсутствие установленной зависимости

Наиболее частый сценарий — модуль не установлен в node_modules.

import lodash from 'lodash';

Если lodash отсутствует в проекте, Rollup не сможет его разрешить.

Причины:

  • пакет не установлен
  • node_modules повреждён
  • используется монорепозиторий без корректных workspace-настроек

Неправильный относительный путь

Ошибка часто возникает при опечатках в путях:

import utils from './util.js';

Файл фактически называется utils.js.

Особенность Rollup: он строго следует файловой системе и не делает «мягких» попыток угадывания.


Отсутствие расширения файла

В конфигурациях без соответствующего плагина резолва:

import helper from './helper';

Если файл существует как helper.js, Rollup без @rollup/plugin-node-resolve не сможет его корректно найти.


Использование Node.js специфичных модулей

import fs from 'fs';

Некоторые встроенные модули Node.js требуют настройки external, иначе Rollup либо помечает их как внешние, либо не может корректно обработать в зависимости от окружения.


Библиотеки с нестандартной структурой экспорта

Некоторые пакеты используют:

  • exports поле в package.json
  • условные экспорты
  • ESM/CJS гибрид

Без соответствующих плагинов резолва Rollup может не понять точку входа:

import something from 'complex-package/sub/module';

Механизм разрешения модулей в Rollup

Rollup сам по себе не является полноценным Node.js резолвером. Он использует плагины для расширения поведения.

Основная цепочка:

  1. Парсинг import
  2. Передача запроса в плагины resolveId
  3. Первый плагин, вернувший путь, «побеждает»
  4. Если ни один плагин не вернул результат → UNRESOLVED_IMPORT

Ключевые плагины:

  • @rollup/plugin-node-resolve
  • @rollup/plugin-commonjs
  • кастомные резолверы

Пример проблемной конфигурации

export default {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.js',
    format: 'esm'
  }
};

При импорте npm-пакета:

import axios from 'axios';

без node-resolve возникает предупреждение.


Исправление через node-resolve

import resolve from '@rollup/plugin-node-resolve';

export default {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.js',
    format: 'esm'
  },
  plugins: [
    resolve()
  ]
};

Теперь Rollup корректно проходит по дереву node_modules.


Конфликты с CommonJS модулями

Даже при наличии node-resolve может возникнуть ситуация, когда пакет экспортируется через CommonJS:

const lib = require('legacy-lib');

Rollup может не интерпретировать такие модули без:

import commonjs from '@rollup/plugin-commonjs';

plugins: [
  resolve(),
  commonjs()
]

Особенности работы с алиасами

При использовании alias-путей:

import Button from '@components/Button';

без настройки алиасов возникает UNRESOLVED_IMPORT.

Решение:

import alias from '@rollup/plugin-alias';
import path from 'path';

export default {
  plugins: [
    alias({
      entries: [
        { find: '@components', replacement: path.resolve(__dirname, 'src/components') }
      ]
    })
  ]
};

Влияние external на предупреждение

Rollup может трактовать импорт как внешний:

external: ['react']

В этом случае:

  • модуль не включается в бандл
  • но UNRESOLVED_IMPORT может появляться, если резолв не совпадает с ожиданиями

Важно различать:

  • external (осознанное исключение)
  • unresolved (ошибка резолва)

Диагностика проблемы

Проверка существования файла

Файловая система:

  • корректность имени
  • регистр символов (особенно в Linux)

Проверка точки входа пакета

package.json:

{
  "module": "dist/index.js",
  "main": "lib/index.js"
}

Некорректное поле может привести к невозможности резолва.


Включение подробного логирования

onwarn(warning, warn) {
  if (warning.code === 'UNRESOLVED_IMPORT') {
    console.log(warning);
  }
  warn(warning);
}

Типичные сценарии в реальных проектах

Монорепозиторий

Проблема:

  • зависимости лежат выше уровня пакета
  • Rollup не видит hoisted node_modules

Решение:

  • корректная настройка workspace
  • явный preserveSymlinks

TypeScript-проекты

При использовании tsconfig paths:

{
  "paths": {
    "@utils/*": ["src/utils/*"]
  }
}

без @rollup/plugin-typescript и alias возникает unresolved import.


Динамические импорты

import(`./modules/${name}.js`);

Rollup не всегда может статически проанализировать такие выражения, что приводит к предупреждениям или необходимости ручного указания manualChunks.


Отличие от других ошибок Rollup

Тип Описание
UNRESOLVED_IMPORT модуль не найден
MISSING_EXPORT нет экспортируемого символа
CIRCULAR_DEPENDENCY циклические зависимости

UNRESOLVED_IMPORT всегда относится к этапу резолва, а не к исполнению или типизации.


Поведение в production-сборке

При --silent или onwarn без обработки:

  • сборка продолжается
  • импорт может быть заменён на undefined или исключён
  • в runtime возможен ReferenceError

Практическая модель устранения

Последовательность анализа:

  1. Проверка пути импорта
  2. Проверка наличия файла или пакета
  3. Проверка node_modules
  4. Проверка плагинов node-resolve и commonjs
  5. Проверка alias-конфигурации
  6. Проверка external
  7. Проверка монорепозитория и symlinks

Поведение Rollup при неразрешённых модулях

Если модуль не найден и не критичен:

  • Rollup оставляет «заглушку»
  • помечает зависимость как external-like
  • генерирует предупреждение

Если модуль критичен для графа:

  • возможен полный провал сборки при строгих настройках плагинов

Связь с архитектурой ESM

ESM требует статического анализа импортов. UNRESOLVED_IMPORT часто является следствием того, что:

  • импорт не может быть вычислен статически
  • путь не существует в момент сборки
  • резолвер не способен интерпретировать структуру пакета

Rollup строго следует ESM-модели и не выполняет код для поиска модулей, что усиливает вероятность появления предупреждения при некорректной структуре проекта.