如何让 Webpack 和 Typescript 使用外部 node_module 文件夹?

How do I get Webpack and Typescript to use an external node_module folder?

设置

我将 bluebird 模块和 @types/bluebird 安装在 node_modules 文件夹中。

我还有一些 .ts 文件将使用 Webpack 打包并在浏览器中使用。

由于各种原因,node_modules 文件夹位于我的 .ts 文件的路径层次结构之外。

问题

我想在我的 .ts 文件中导入 bluebird 模块,这样:

  1. 我得到了打字。
  2. Webpack 将解析模块并将其包含在输出包中。

如果 node_modules 在路径层次结构中的正确位置,我可以简单地这样做:

import * as Promise from 'bluebird'

Typescript 编译器(通过 ts-loader)解析为 node_modules/@types/bluebird 中的类型定义并对代码进行类型检查,Webpack 解析为 node_modules/bluebird 中的实际模块并将其发出捆绑。

但是,对于外部 node_modules 文件夹,我无法使其正常工作。

我尝试过的方法

到目前为止,我能够得到它,所以 Typescript 是快乐的,但不是 Webpack。

1.在tsconfig.ts

中设置baseURLpaths

对我来说最明显的解决方案似乎是设置 baseURL 并将 paths 设置到 tsconfig.json 中的 node_modules 中,像这样(shared 包含 node_modules 文件夹):

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

但是我做不到:

import * as Promise from 'shared/node_modules/bluebird'

我需要:

import * as Promise from 'shared/node_modules/@types/bluebird/index'

但是这个导入不适用于 Webpack。它要么找不到它,要么如果我配置它找到它,ts-loader 不会喜欢编译它(因为它是一个声明文件),或者如果我配置它忽略它,它会在运行时崩溃,因为它不在那里。

2。相对导入

我尝试在 node_modules 文件夹中指定一个相对路径,但最终遇到了大致相同的问题。

我对这个问题采用了一个有点老套的解决方案。

我遇到的问题的症结在于我需要单个 import 语句来由 Typescript 和 Webpack 以不同的方式解决。 Typescript 需要解析为类型定义,Webpack 需要解析为模块。

为了实现这一点,我在 tsconfig.json 中使用 paths 将导入指向类型定义,并在 webpack.config.js 中使用 resolve.alias 将相同的导入指向实际模块。

tsconfig.json:

{
    "compilerOptions": {
        "baseUrl":"..",    // you need this to set paths below.
        "paths":{
             "shared/bluebird":["shared/node_modules/@types/bluebird/index"]
        }
        ...
    }
}

webpack.config.js

resolve: {
    alias: {
        "shared/bluebird": path.resolve(__dirname, '../shared/node_modules/bluebird')
    }
    ...
}

这允许我做:

import * as Promise from 'shared/bluebird'

Typescript 和 Webpack 都很开心。