如何防止 TypeScript 中断基于 Webpack 的 ProvidePlugin 上声明的未解析变量的 Webpack 构建?

How to prevent TypeScript from interrupting Webpack building on unresolved variables declared on Webpack's ProvidePlugin?

在打字稿编译器开始对实际上已经在 webpack 的 ProvidePlugin 配置中配置的未解析变量大喊大叫后,有没有办法防止 WebPack 的构建过程失败?

webpack.config.js

plugins: [
...
new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            "window.jQuery": "jquery",
            "_": "underscore",
            "underscore": "underscore"
            //'process.env.NODE_ENV': '"development"'
        }),

]

tsconfig.json

{
  "compilerOptions": {


    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "suppressImplicitAnyIndexErrors": true,
    "declaration": false
  },
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ]
}

https://webpack.github.io/docs/list-of-plugins.html#provideplugin

根据我的经验,打字稿不知道哪些变量将被注入到模块中,因此构建没有完成。

这是构建的输出

ERROR in ./src/file1.component.ts
(77,9): error TS2304: Cannot find name '$'.

ERROR in ./src/file2.component.ts
(78,13): error TS2304: Cannot find name '$'.

ERROR in ./src/file3.ts
(155,15): error TS2304: Cannot find name 'jQuery'.

ERROR in ./src/file4.ts
(108,9): error TS2304: Cannot find name '$'.

如果我对 ProvidePlugin 的理解正确,您仍然需要将 jQuery 和下划线声明为模块(外部或别名)。

因此我建议在 TypeScript 中加载这些模块:

import * as $ from 'jquery';
import * as _ from 'underscore';

那么您只需要为这些库提供定义 (.d.ts) 文件。为此,我推荐 typings

typings install jquery --global
typings install underscore --global

我假设您使用的是 ts-loader,它将自动处理。

如果您想避免 import 语句,您仍然可以使用类型定义声明这些库。

或者您可以创建自己的简化声明:

declare var jQuery: any;
declare var $: any;

我对 ahz 的回答并不完全满意,因为我不喜欢全局安装类型或声明 jQueryany 丢失所有类型检查。

对我有用的解决方案是创建具有以下内容的 global.d.ts

import * as _jQuery from 'jquery';

declare global {
  const jQuery: typeof _jQuery;
  const $: typeof _jQuery;
}

在那之后 tsc 就通过了,没有像 Cannot find name '$'. 那样的任何警告。

找到 here

我要添加到最上面的答案中,说有一些例外,下面是解决方法。我 运行 使用 Ant-Design 和 Redux 解决了这个问题。

当你使用这个时:

import _Fake from 'fake-lib'

declare global {
  const Fake: typeof _Fake
}

它有效,但仅适用于作为命名空间导出的库(如 React)。在这种情况下,您可以放心地这样做:

const x: Fake.Property // GOOD: Fake acts as a namespace
Fact.Function          // GOOD: Fake acts a concrete type that contains Function

另一方面,我有一些库没有导出为命名空间(如 Redux)并导致了这个:

const x: Fake.Property // FAIL: Fake is not a namespace
Fact.Function          // GOOD: Fake acts a concrete type that contains Function

为了避免这个问题,您基本上可以 globally-augment 库被视为命名空间导出,如下所示:

修改您的 tsconfig.json 以添加新的技巧

"compilerOptions": {
    ...
},
"include": [
    "./src/**/*",
    "./types/**/*"
]

并添加一个包含

types/fake.d.ts文件
import * as Fake from 'fake-library'

export as namespace Fake
export = Fake

现在完成这些更改后,全局 const 声明将正常工作。

不要 babel-loader 在 babel 7 上使用 ts-loader(删除这个!)!我希望这可以节省将来调试的人!