Tsc throws `TS2307: не удается найти модуль` для локального файла

У меня есть простой пример с использованием TypeScript: https://github.com/unindented/ts-webpack-example

Запуск tsc -p .tsc версия 1.8.10) вызывает следующее:

app/index.ts(1,21): error TS2307: Cannot find module 'components/counter'.
components/button/index.ts(2,22): error TS2307: Cannot find module 'shared/backbone_base_view'.
components/button/index.ts(3,25): error TS2307: Cannot find module 'shared/backbone_with_default_render'.
components/counter/index.ts(2,22): error TS2307: Cannot find module 'shared/backbone_base_view'.
components/counter/index.ts(3,25): error TS2307: Cannot find module 'shared/backbone_with_default_render'.
components/counter/index.ts(4,27): error TS2307: Cannot find module 'shared/backbone_with_subviews'.
components/counter/index.ts(5,20): error TS2307: Cannot find module 'components/button'.

Он жалуется на все импорт локальных файлов, например:

import Counter from 'components/counter';

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

import Counter from '../components/counter';

Кодовая база vscode не использует относительные пути, но для них все отлично работает, поэтому я должен что-то пропускать в своем проекте: https://github.com/Microsoft/vscode/blob/0e81224179fbb8f6fda18ca7362d8500a263cfef/src/vs/languages/typescript/common/typescript.ts#L7-L14

Вы можете проверить мой репозиторий GitHub, но в случае, если он помогает мне использовать файл tsconfig.json, который я использую:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "noImplicitAny": false,
    "removeComments": false,
    "preserveConstEnums": true,
    "sourceMap": true,
    "outDir": "dist"
  },
  "exclude": [
    "dist",
    "node_modules"
  ]
}

Забавно, что проект с помощью webpack с помощью ts-loader работает отлично, поэтому я предполагаю, что это просто проблема с конфигурацией...

Ответ 1

@vladima ответила на эту проблему на GitHub:

Способ управления модулями компилятора контролируется moduleResolution, который может быть либо node, либо classic (подробнее подробности и различия можно найти здесь). Если этот параметр опущен компилятор рассматривает этот параметр как node, если модуль commonjs и classic - в противном случае. В вашем случае, если вам нужен модуль classicстратегии разрешения, которые будут использоваться с модулями commonjs - вам необходимо установить это явно с помощью

{
    "compilerOptions": {
        "moduleResolution": "node"
    }
}

Ответ 2

Кодовая база vscode не использует относительные пути, но все работает отлично для них

Действительно зависит от вашего загрузчика модуля. Если вы используете systemjs с baseurl, тогда это сработает. VSCode использует собственный пользовательский загрузчик модулей (на основе старой версии requirejs).

Рекомендация

Используйте относительные пути, которые поддерживает commonjs. Если вы перемещаете файлы вокруг, вы получите ошибку времени компиляции typescript (хорошая вещь), поэтому вам будет лучше, чем подавляющее большинство проектов чистого js там (на npm).

Ответ 3

В моем случае,

   //app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
            //{
            //    HotModuleReplacement = true
            //});

я прокомментировал это в startup.cs

Ответ 4

В VS2019 на странице свойств проекта вкладка TypeScript Build имеет параметр (раскрывающийся список) для "Модульная система". Когда я изменил это значение с "ES2015" на CommonJS, то интегрированная среда разработки VS2019 перестала жаловаться, что не может найти ни axios, ни redux-thunk (TS2307).

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "src",
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "lib": [
      "es6",
      "dom",
      "es2015.promise"
    ],
    "module": "esnext",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "outDir": "build/dist",
    "rootDir": "src",
    "sourceMap": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "target": "es5",
    "skipLibCheck": true,
    "strict": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "exclude": [
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts",
    "node_modules",
    "obj",
    "**/*.spec.ts"
  ],
  "include": [
    "src",
    "src/**/*.ts",
    "@types/**/*.d.ts",
    "node_modules/axios",
    "node_modules/redux-thunk"
  ]
}