Проблема с конфигурацией TypeScript для компиляции Webpack: ошибка “Файл ‘…’ не находится под ‘rootDir’ ‘…'”

Вопрос или проблема

Я разрабатываю расширения для VSCode. В проекте есть две директории:

a) core: содержит основные модули, используемые другими расширениями

b) extension: содержит код, связанный с расширением

Обе директории находятся в корне проекта и имеют свой собственный файл tsconfig. Мне нужно получить доступ к модулям, расположенным в директории ‘core‘, из директории ‘extension‘. Когда я запускаю “tsc”, компиляция проходит успешно, но когда я запускаю компиляцию webpack (выполняя команду ‘webpack’), я получаю эту ошибку:

TS6059: Файл 'C:/.../extensions/core/api/HttpApiService.ts' не находится в 'rootDir' 'C:/.../extensions/extension'. Ожидается, что 'rootDir' будет содержать все исходные файлы.
  Файл в программе, потому что:
    Основной файл указан для компиляции
    Импортирован через "../api/HttpApiService" из файла 'C:/.../extensions/extension/core/vscode/Ioc.ts' 

Вот содержимое файлов tsconfig.json:

core/tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "lib": ["dom", "ES2022"],
    "types": ["node", "reflect-metadata"],
    "rootDir": ".",
    "outDir": "./.out",
    "strict": true,
    "sourceMap": true,
    "composite": true,
    "verbatimModuleSyntax": true,
    // ОТКЛЮЧЕНО: Webpack не может разрешить эти алиасы (вероятно, отсутствует какая-то конфигурация)
    // "paths": {
    //   "@/*": ["./*"]
    // },
    // конфигурация inversify:
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  },
  "exclude": ["node_modules"],
  "include": ["./**/*"]
}

extension/tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "module": "esnext",
    "moduleResolution": "node",
    "lib": ["es6", "dom"],
    "outDir": ".out",
    "rootDirs": ["./", "../core"],
    "strict": true, 
    "sourceMap": true,
    "allowSyntheticDefaultImports": true,
    "composite": true,
    "noEmit": true,
    "verbatimModuleSyntax": true,
    "paths": {
      "core/*": ["../core/*"], 
      "@core/*": ["../core/*"], 
      "@/*": ["./*"] 
    }
  },
  "exclude": ["node_modules"],
  "include": ["./**/*", "../core/**/*"],
  "references": [
    {
      "path": "../core"
    }
  ]
}

А вот конфигурация webpack:

//@ts-check

"use strict";

const path = require("path");

//@ts-check
/** @typedef {import('webpack').Configuration} WebpackConfig **/

/** @type WebpackConfig */
const extensionConfig = {
  target: "node", // Расширения VS Code работают в контексте Node.js 📖 -> https://webpack.js.org/configuration/node/
  mode: "none", // это оставляет исходный код как можно более близким к оригиналу (при упаковке мы устанавливаем это значение в 'production')

  entry: "./src/extension.ts", // входная точка этого расширения, 📖 -> https://webpack.js.org/configuration/entry-context/
  output: {
    // пакет хранится в папке 'dist' (проверьте package.json), 📖 -> https://webpack.js.org/configuration/output/
    path: path.resolve(__dirname, "dist"),
    filename: "extension.js",
    libraryTarget: "commonjs2",
  },
  externals: {
    vscode: "commonjs vscode", // модуль vscode создается на лету и должен быть исключен. Добавьте другие модули, которые не могут быть собраны webpack, 📖 -> https://webpack.js.org/configuration/externals/
    // модули, добавленные здесь, также нужно добавить в файл .vscodeignore
  },
  resolve: {
    // поддержка чтения файлов TypeScript и JavaScript, 📖 -> https://github.com/TypeStrong/ts-loader
    extensions: [".ts", ".js"],
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "ts-loader",
            options: {
              configFile: "tsconfig.json",
            },
          },
        ],
      },
    ],
  },
  devtool: "nosources-source-map",
  infrastructureLogging: {
    level: "log", // включает ведение журнала, необходимое для сопоставления проблем
  },
};
module.exports = [extensionConfig];

Я использую следующие зависимости webpack:

"webpack": "^5.91.0",
"webpack-cli": "^5.1.4",

В ‘extension/tsconfig.json’ я пробовал добавлять дополнительные настройки, но ни одна из них не помогла. Я пробовал следующее:

  • включить директорию core: “include”: [“../core/**/*”]
  • настроить несколько rootDirs: “rootDirs”: [“./”, “../core”]
  • установить “rootDir”: “rootDir”: “../”

Я не понимаю, почему tsc проходит успешно, а компиляция webpack — нет, так как, по моим представлениям, они обе должны использовать (по крайней мере, в моем понимании) одно и то же определение tsconfig.

Ответ или решение

Проблема, с которой вы столкнулись, связана с конфигурацией TypeScript и Webpack, а именно с настройками rootDir и пониманием того, какие файлы должны быть включены в компиляцию. Давайте разберем возможные решения проблемы, а именно ошибку, указывающую, что файл ‘…’ не находится под ‘rootDir’ ‘…’.

Проблема:

Ошибка компиляции Webpack, связанная с TypeScript, возникает из-за того, что Webpack (с использованием ts-loader) пытается собрать файл, который находится вне указанной директории rootDir, установленной в вашем tsconfig.json.

Объяснение:

Когда вы компилируете ваш проект с помощью tsc, компилятор TypeScript имеет возможность обрабатывать файлы в соответствии с вашими настройками include и exclude. Однако ts-loader, который используется в Webpack, требует, чтобы все исходники были расположены в пределах rootDir. В вашем случае, если rootDir указывает на ./ в extension/tsconfig.json, то TypeScript ищет файлы только в этой директории.

Что можно сделать:

  1. Измените rootDir:

    Вы можете попробовать изменить rootDir в extension/tsconfig.json на более высокий уровень, чтобы включить как core, так и extension директории. Например:

    "compilerOptions": {
     "rootDir": "..",  // Поменяйте `rootDir` на уровень выше
    }
  2. Проверьте include и exclude:

    Убедитесь, что в extension/tsconfig.json вы включает в себя все необходимые файлов:

    "include": ["./**/*", "../core/**/*"]
  3. Обновите webpack.config.js:

    Убедитесь, что вы указываете правильный configFile в ts-loader. Если ваш tsconfig для расширений называется tsconfig.json, настройка должна работать. Но если он находится в другом месте, укажите путь к нему:

    use: [
     {
       loader: "ts-loader",
       options: {
         configFile: path.resolve(__dirname, 'tsconfig.json'), // или укажите полный путь к tsconfig
       },
     },
    ],
  4. Изменение paths:

    Вам следует попробовать упростить ваши пути, возможно, изменить их, чтобы они не конфликтовали. Например, если вы используете paths, как указано:

    "paths": {
     "core/*": ["../core/*"],
     "@core/*": ["../core/*"],
     "@/*": ["./*"]
    }

    Убедитесь, что вы корректно используете их в импортируемых модулях.

  5. Проверка ссылок на другие модули:

    В extension/tsconfig.json тоже убедитесь, что references корректно ссылаются на core, это может помочь TypeScript корректно отслеживать зависимости и транспонировать их:

    "references": [
     { "path": "../core" }
    ],

Заключение:

Попробуйте внести вышеуказанные изменения и запустите Webpack заново. Если ошибка все еще сохраняется, внимательно проверьте вывод Webpack на наличие дополнительных подсказок, и убедитесь, что все директории правильно настроены и указаны. Это должно помочь вам успешно собрать ваше расширение с использованием Webpack.

Оцените материал
Добавить комментарий

Капча загружается...