Webpack的resolve.alias与TypeScript无法配合使用?

83

我试图在TypeScript中缩短我的导入:

import {Hello} from "./components/Hello";

import {Hello} from "Hello";

为此,我发现可以在webpack中使用resolve.alias,因此我配置了以下部分:

resolve: {
    root: path.resolve(__dirname),
    alias: {
        Hello: "src/components/Hello"
    },
    extensions: ["", ".ts", ".tsx", ".js"]
},

Webpack构建成功,输出的bundle.js文件可用。然而,TypeScript的智能提示会抱怨它找不到该模块。

我的问题是webpack的resolve.alias是否适用于TypeScript?

我发现了这个问题,但没有答案。


1
2022年新手快速链接:https://dev59.com/CFkS5IYBdhLWcg3wDyn5#69323871 - VimNing
9个回答

102

如果您正在使用ts-loader,则可能需要将 webpack 的alias/resolve设置与tsconfig.json中的paths设置同步。

{
    "compilerOptions": {
        "baseUrl": "./",
        "paths": {
            "Hello": ["src/components/Hello"]
        }
    }
}

如果您正在使用awesome-typescript-loader,那么webpack可以自动从tsconfig.json中的paths设置中找到这个信息,详情请参见存储库上有关此问题的状态。这样,您就不需要在Webpack的alias字段中重复相同的信息。


1
似乎我需要在使用awesome-typescript-loader时也设置paths属性。我正在使用webpack1和awesome-typescript-loader 1.1.1。但是它仍然可以工作 :) - starcorn
5
这已经是我第二次遇到这个问题了..请确保在设置路径时设置baseUrl,两者都需要。 - SgtPooki
新建一个Angular CLI项目,添加app/components文件夹,并将app.component移动到它自己的文件夹中。在tsconfig中添加baseUrl:“。”和paths:{"c":["src/app/components"]}(c表示components)。添加index.d.ts并导出"./app.component/app.component"。npm安装awesome-typescript-loader。VS Code可以解析import {AppComponent} from "c";(鼠标悬停显示正确路径)。ng build -> ERROR in C:/Temp/a4-cli-test/src/app/app.module.ts (4,30): Cannot find module '~c'。我有什么遗漏吗? - Drusantia
1
就我个人而言,我无法仅使用 TsConfigPathsPlugin(如在 awesome-typescript-loader 的 README 中所述)使其正常工作,但是像 ts-loader 一样同步配置似乎可以解决问题。 - Shepmaster
当您查看bundle.js时,您是否期望在其中看到别名,还是期望将其转换为映射? - darewreck
显示剩余4条评论

93

tsconfig.json中,你漏掉了一个非常重要的点:匹配模式!

它应该像这样配置:

"baseUrl": ".",
"paths": {
    "appSrc/*": [
        "src/*"
    ]
 }

"*"是告诉TS要匹配右侧任何内容的重要部分。

我从这篇文章中发现了这一点:Type-safe es2015 module import path aliasing with Webpack, Typescript and Jest

注意:

  • 确保您所有的webpack.config.js都已更新(例如,如果您使用storybook)。
  • 如果您使用Visual Studio Code,则可能需要重新启动它,以使下划线消失。

11
应该将这个标记为正确答案。我的IDE也需要这个才能捕捉自动完成。 - Juan Treminio
6
为了生效,我不得不重新启动一次VSCode。 - Meanman
3
可以确认,这比被采纳的答案对我更有帮助,因为我把目录设置成了别名。 - Chris
3
这个回答立刻解决了我在VS Code中的所有问题,应该被接受作为答案。 - Eric
不适用于我。但是Daniel Rosenwasser的答案确实有效。 - sakramento
立即修复了问题。唯一的注意事项是它不喜欢我的别名大小写与目录大小写不匹配,所以我改成了匹配的大小写。 - Syknapse

43

正如其他人所提到的,你需要在webpack.config.js中提供一个alias:

    resolve: { 

        extensions: [".ts", ".js"],
        alias: {
            forms: path.resolve(__dirname, "src/forms/")
        } 
    },

这需要与你的 tsconfig.json 文件同步 (baseUrl 和 paths 是必需的)。

"compilerOptions":  {
    baseUrl: "./",
    ...
    paths: {
       "forms/*": ["src/forms/*"]
    }
}
注意:通配符模式是必要的,以匹配您的解析别名配置。
然后,您可以使用您的别名导入任何库:
import { FormsModule } from "forms/my-forms/my-forms.module";

有没有一种方法可以配置webpack,以支持不带斜杠的路径“~*”:[“src / *”],这也是由TS(tsconfig.json)和VSCode支持的?结果是import x from'〜components / x,它被翻译为src / components / x - Qwerty
这是唯一对我有效的解决方案。谢谢。 - zrna
这对我有用:Webpack 4.35.2和Typescript 2.8和AT-Loader 5.0。 - andy
对我有用,如果您遇到与node_modules依赖项相关的构建错误,请查看以下内容:https://github.com/netlify/netlify-lambda/issues/179#issuecomment-531468792 - helsont

13

您还可以配置tsconfig-paths-webpack-plugin,以便不需要在多个地方重复使用别名。它将从tsconfig.json文件中获取别名并自动将它们添加到webpack中。


如果使用 webpack,这应该是第一篇答案。谢谢。 - Matt Young

10
如果您仍然遇到此问题,请不要忘记像这样将您的文件夹添加到tsconfig.json的“include”选项中:
{
  "compilerOptions": {
    "sourceMap": true,
    "allowJs": true,
    "baseUrl": "./",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "lib": [
      "es2016",
      "dom"
    ]
  },
  "outDir": "./built/",
  "include": [
    "./src/**/*",
    "./tests/**/*"
  ]
}

5

我需要对Caio Saldanha的解决方案进行小的调整,以使其适用于我的环境。

我正在使用带有babel-plugin-module-resolver的Babel 7来解析别名。由于Babel 7使用@babel/preset-typescript支持TypeScript,因此没有使用ts-loaderawesome-typescript-loader。我不得不为每个别名添加额外的路径配置,以自动加载模块根目录(例如index.ts):

"baseUrl": ".",
"paths": {  // this must be synchronized with .babelrc.js's module-resolver alias config
    "component": ["src/component/index.ts"],
    "component/*": ["src/component/*"],
    ...
}

/component文件夹中有一个index.ts文件,其内容如下:
export { default as Logo } from './Logo';

没有额外的.../index.ts行,这个导入对我来说不起作用:
import { Logo } from 'component';  

.babelrc.js中的别名配置:
plugins: [
[
    'module-resolver',
    {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
        root: ['./src'],
        alias: {
        // this must be synchronized with tsconfig.json's path configuration
            component: './src/component',
        },
    },
],

嗨@AMilassin,你能确认你在项目中没有使用ts-loader和babel吗?谢谢。 - kalwalt
我已经配置了ts-loader和webpack进行编译,使用tsc进行类型检查。 - AMilassin
@kalwalt:在Babel 7中,你不需要使用ts-loader。 - VimNing

1

有两种情况:

  1. 当您编写自定义webpack时,它可以与TypeScript一起使用,但不能直接使用。为了解释清楚,在后台会发生两种类型的编译。首先是tsx -> js,对此tsconfig.json起着重要作用,但当您实际编译js代码时,webpack就会出现在画面中。因此,为了成功运行应用程序,别名和解析应该放置在tsconfig和webpack的两个地方。
  2. 当您使用默认值(创建React应用程序后)时:您只需要在tsconfig中添加"baseUrl": "./src",然后查看代码即可正常工作。

1

仅为一个特定组件使用别名并不是一个好的做法,你应该告诉 webpack 配置文件,在我的 ts-config 中已经设置了现有的别名,可以使用 tsconfig-paths-webpack-plugin,以下是示例配置:

// webpack.config.js
module.exports = {
  ...
  resolve: {
    plugins: [new TsconfigPathsPlugin({/* options: see below */})]
  }
  ...
}

//ts-config.json
{
  "compilerOptions": {
    "baseUrl": "./src",
    "components/*": "components/*"
    ...
  },
  ...
}


第二个解决方案是,你可以手动解决这个问题,通过在webpack.config中指定你想要的别名。但如果你不想这样做,你可以按照上述配置进行操作。
// webpack.config.js
module.export = {
  resolve: {
    alias: {
      'components': path.resolve(__dirname, 'src/components')
    }
  }
}

记住 tsconfigjsconfig 的作用是为您的编辑器提供智能感知,并为您的打包工具提供指导。
//ts-config.json
{
  "compilerOptions": {
    "baseUrl": "./src",
    "components/*": "components/*"
    ...
  },
  ...
}

无论你选择了什么解决方案,你都应该继续使用它。
import {Home} from 'components';
...

如果您对于webpack.config如何依赖于您的tsconfig.json感到好奇,您可以阅读ts-loader


-3

我认为你可以这样做,并且使它按照你所描述的方式工作:

resolve: {
    root: [
        path.resolve(__dirname),
        <path_to_components_directory> //e.g. path.resolve(__dirname, 'src', 'components')
    ], 
    extensions: ["", ".ts", ".tsx", ".js"]
},

然后你可以执行 import {Hello} from "Hello";

我知道我这样做是为了解决在我的src/js目录中的文件路径。虽然我没有使用typescript,但我不认为它会影响结果。


3
但是 TypeScript 在这里是问题所在。 - Luckylooke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接