为什么 VSCode 不在 tsconfig 中获取路径别名?

Why does VSCode not pick up path aliases in tsconfig?

我有一个 jsconfig.json,我用 tsconfig.json 替换了它。替换后,VSCode 不获取路径别名并报告导入错误:

示例:

Cannot find module '@Components/Title' or its corresponding type declarations.ts(2307)

jsconfig.json

// https://code.visualstudio.com/docs/languages/jsconfig

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@Components/*": ["./src/components/*"],
            "@Modules/*": ["./src/modules/*"],
            "@Styles/*": ["./src/styles/*"],
            "@Content/*": ["./src/content/*"],
            "@Apps/*": ["./src/apps/*"]
        }
    },
    //Add any build/compiled folders here to stop vscode searching those
    "exclude": ["node_modules", "build"]
}

tsconfig.json

// https://code.visualstudio.com/docs/languages/jsconfig
{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@Components/*": ["./src/components/*"],
            "@Modules/*": ["./src/modules/*"],
            "@Styles/*": ["./src/styles/*"],
            "@Content/*": ["./src/content/*"],
            "@Apps/*": ["./src/apps/*"]
        },
        "target": "es5",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": false,
        "forceConsistentCasingInFileNames": true,
        "noEmit": true,
        "incremental": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "jsx": "preserve"
    },
    "exclude": ["node_modules", "build"],
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

更新 1:我只对以 .js 结尾的文件有这个问题。如果我将它们重命名为 .ts 一切正常。奇怪的是,如果我将文件重命名回 .js 并重新启动 VSCode,错误将不再显示在文件中。

问题是 TypeScript 的编译器会保留源代码中写入的路径,正如您在此 GitHub issue 中看到的那样,这使得 tsc 无法用于您的用例。

由于您显然是在构建 Web 应用程序,因此我将提供一个基于 Webpack 的最小解决方案,Webpack 是最流行的 Web 捆绑器之一。

.
├── src
│   ├── components
│   │   └── component.ts
│   └── index.ts
├── package.json
├── tsconfig.json
└── webpack.config.js

src/index.ts

import { Component } from '@Components/component';
Component.log();

src/components/component.ts

export class Component {
    static log() {
        console.log("test");
    }
}

package.json

{
  "name": "70072923",
  "version": "1.0.0",
  "description": "",
  "main": "src/index.js",
  "devDependencies": {
    "ts-loader": "^9.2.6",
    "tsconfig-paths-webpack-plugin": "^3.5.2",
    "typescript": "^4.5.2",
    "webpack": "^5.64.4",
    "webpack-cli": "^4.9.1"
  },
  "scripts": {
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

tsconfig.json

{
    "compilerOptions": {
        "baseUrl": "src",
        "paths": {
            "@Components/*": ["components/*"],
        },
        "target": "es5",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": false,
        "forceConsistentCasingInFileNames": true,
        "incremental": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "jsx": "preserve"
    },
    "exclude": ["node_modules", "build"],
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

webpack.config.js

const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
    entry: './src/index.ts',
    resolve: {
        extensions: ['.ts'],
        plugins: [
            new TsconfigPathsPlugin,
        ]
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
};

使用 npm run build 构建项目,它输出一个准备执行的最小独立文件:

dist/bundle.js

(()=>{"use strict";(class{static log(){console.log("test")}}).log()})();

完整项目在这里:https://github.com/Guerric-P/Webpack-and-TypeScript-path-mappings

tsconfig 配置只适用于“include”选项匹配的文件,不被“exclude”选项排除。您的“包含”选项仅匹配 .ts 和 .tsx 文件,但不匹配 .js 文件

将“**/*.js”添加到包含的 glob 列表中,它应该可以工作。