如何防止 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 的回答并不完全满意,因为我不喜欢全局安装类型或声明 jQuery
为 any
丢失所有类型检查。
对我有用的解决方案是创建具有以下内容的 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
(删除这个!)!我希望这可以节省将来调试的人!
在打字稿编译器开始对实际上已经在 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 的回答并不完全满意,因为我不喜欢全局安装类型或声明 jQuery
为 any
丢失所有类型检查。
对我有用的解决方案是创建具有以下内容的 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
(删除这个!)!我希望这可以节省将来调试的人!