Avatar ·

Ошибка ESLint "Unable to resolve path to module" при импорте TypeScript-файлов

Привет, коллеги! Я только начал осваивать TypeScript и пытаюсь настроить ESLint в своём проекте, но столкнулся с очень странной ошибкой. У меня есть простая структура проекта: ``` src/ utils/ helpers.ts components/ Button.tsx index.ts ``` В файле `index.ts` я пытаюсь импортировать модуль: ```typescript import { formatDate } from './utils/helpers'; ``` ESLint выдаёт ошибку: `Unable to resolve path to module './utils/helpers'`. При этом сам TypeScript прекрасно видит этот файл и код компилируется без ошибок! Мой конфиг ESLint (`.eslintrc.json`): ```json { "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended" ] } ``` Я уже пробовал: - Указывать полный путь с расширением `.ts` — не помогает - Добавлять `import/resolver` в настройки — тоже без результата - Переустанавливать node_modules — ошибка остаётся Подскажите, пожалуйста, в чём может быть проблема? TypeScript работает нормально, а ESLint ругается на импорты. Как правильно настроить ESLint для TypeScript-проекта, чтобы он понимал пути к модулям? Версии: TypeScript 5.3, ESLint 8.56, @typescript-eslint/parser 6.19. <<>>

Причина ошибки

Ошибка Unable to resolve path to module возникает из-за того, что ESLint использует стандартный Node.js резолвер для поиска модулей, который ищет файлы с расширениями .js, .json и .node. TypeScript-файлы (.ts, .tsx) не входят в этот список по умолчанию. При этом сам TypeScript имеет свою собственную систему разрешения модулей, которая учитывает его расширения.

Решение: настройка eslint-import-resolver-typescript

Для правильной работы ESLint с TypeScript необходимо установить и настроить плагин eslint-plugin-import вместе с резолвером eslint-import-resolver-typescript. Этот резолвер научит ESLint понимать TypeScript-расширения и учитывать настройки tsconfig.json.

Шаг 1: Установка зависимостей

npm install --save-dev eslint-plugin-import eslint-import-resolver-typescript

Шаг 2: Обновление конфигурации ESLint

В вашем .eslintrc.json нужно добавить плагин import и настроить резолвер:

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint", "import"],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:import/recommended",
    "plugin:import/typescript"
  ],
  "settings": {
    "import/resolver": {
      "typescript": {
        "alwaysTryTypes": true,
        "project": "./tsconfig.json"
      }
    }
  },
  "rules": {
    "import/no-unresolved": "error"
  }
}

Шаг 3: Проверка tsconfig.json

Убедитесь, что ваш tsconfig.json корректно настроен. Минимальная конфигурация:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"],
  "exclude": ["node_modules"]
}

Дополнительные рекомендации

  • Укажите расширения для импортов: В правиле import/extensions можно настроить, какие расширения нужно указывать явно:
    "rules": {
      "import/extensions": ["error", "ignorePackages", {
        "ts": "never",
        "tsx": "never"
      }]
    }
  • Для монорепозиториев: Если у вас несколько tsconfig-файлов, укажите их в массиве:
    "settings": {
      "import/resolver": {
        "typescript": {
          "project": [
            "packages/*/tsconfig.json",
            "apps/*/tsconfig.json"
          ]
        }
      }
    }
  • Проверка путей: Убедитесь, что ваш baseUrl в tsconfig.json соответствует структуре проекта. Если вы используете алиасы (например, @/components/Button), резолвер автоматически их поддержит.

Проверка решения

После настройки выполните ESLint снова:

npx eslint src/index.ts

Ошибка Unable to resolve path to module должна исчезнуть, а импорты TypeScript-файлов будут корректно обрабатываться.

Если проблема осталась

  • Перезапустите редактор кода (особенно если используете VSCode с расширением ESLint)
  • Проверьте, что все зависимости установлены в одной директории (не глобально)
  • Убедитесь, что ваш tsconfig.json находится в корне проекта и ESLint видит его
<<>>

Альтернативный подход: использование @typescript-eslint/eslint-plugin

Если вы не хотите подключать дополнительный плагин eslint-plugin-import, можно решить проблему другим способом — настроить ESLint через @typescript-eslint/parser с дополнительными опциями.

Настройка parserOptions

Добавьте в .eslintrc.json следующие настройки:

{
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "./tsconfig.json",
    "tsconfigRootDir": ".",
    "ecmaVersion": 2020,
    "sourceType": "module"
  },
  "plugins": ["@typescript-eslint"],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking"
  ],
  "rules": {
    "@typescript-eslint/no-unused-vars": "error"
  }
}

Важные моменты

  • Этот подход использует TypeScript-компилятор для разрешения модулей, что может замедлить линтинг на больших проектах
  • Требуется, чтобы tsconfig.json был корректным и включал все необходимые файлы
  • Не поддерживает алиасы путей из коробки — нужно дополнительно настраивать через import/resolver

Когда это подходит

Этот метод хорош для небольших проектов или когда вы уже используете типизированные правила (recommended-requiring-type-checking). Для крупных проектов с большим количеством файлов и алиасами путей лучше использовать первый вариант с eslint-import-resolver-typescript.