我最近升级到Webpack 5,在导入UMD模块时遇到一些问题。
特别是,我正在尝试进口传单。传单似乎导出了一个由rollup.js创建的UMD模块,它看起来像这样:
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.L = {})));
}(this, (function (exports) { 'use strict';
[...]
})));
正如您所看到的,它首先尝试使用CommonJS(如果定义了exports
和module
(,然后尝试使用AMD(如果定义define
(,否则它试图通过从模块上下文引用this
将自己置于全局范围。
Webpack(没有任何加载程序(将其编译为:
(function (global, factory) {
typeof exports === 'object' && "object" !== 'undefined' ? factory(exports) :
typeof define === 'function' && __webpack_require__.amdO ? define(['exports'], factory) :
(factory((global.L = {})));
}(undefined, (function (exports) { 'use strict';
[...]
})));
具体来说,它所做的是:
- 用
"object"
替换typeof module
- 用
__webpack_require__.amd0
替换define.amd
- 将
this
替换为undefined
在构建过程中,webpack向我发出警告:export 'default' (imported as 'L') was not found in 'leaflet' (possible exports: )
。当我在浏览器中打开编译后的捆绑包时,我会得到错误Uncaught TypeError: Cannot set property 'L' of undefined
。
发生的情况是CommonJS失败(因为未定义exports
(,AMD失败(因为没有定义define
(,最后设置全局也失败,因为this
被undefined
替换。
根据Webpack文档,Webpack应该普遍支持导入CommonJS和AMD模块,但在这种情况下,这两者似乎都不起作用。
我能做些什么来解决这个问题?
我缩小了问题范围,发现问题是由我以某种方式使用imports-loader
引起的。
在更新之前,我使用了imports-loader
来添加依赖项没有导入的任何所需的可传递依赖项,特别是CSS文件。配置看起来像这样:
{ module: { rules: [ {
test: //node_modules/leaflet/.*.js$/,
loader: "imports-loader?asdf=leaflet/dist/leaflet.css"
} ] } }
升级后,webpack不再接受loader的字符串语法,imports-loader也更改了语法,所以我将其更改为:
{ module: { rules: [ {
test: //node_modules/leaflet/.*.js$/,
loader: "imports-loader",
options: {
imports: "default leaflet/dist/leaflet.css asdf"
}
} ] } }
这似乎完成了任务,并正确地包含了必要的CSS文件。然而,当我发现配置的这一部分是问题的原因时,我深入研究了imports-loader
的文档。事实证明,我使用的配置现在生成了以下代码行:
import asdf from "leaflet/dist/leaflet.css";
(我本可以使用"side-effects leaflet/dist/leaflet.css"
来获得相同的结果,而不必使用asdf
作为伪导入名称(。虽然这正确地导入了CSS文件,但可能会导致webpack认为该文件是一个正确的ES模块,从而禁用对CommonJS/AMD/UMD模块的支持。我将导入加载程序的配置更改为以下内容:
{ module: { rules: [ {
test: //node_modules/leaflet/.*.js$/,
loader: "imports-loader",
options: {
imports: "pure leaflet/dist/leaflet.css",
type: "commonjs"
}
} ] } }
根据文档,这创建了以下代码行:
require("leaflet/dist/leaflet.css");
在做出这一改变之后,它似乎没有问题。
有趣的是,看起来webpack实际上检测到了整个UMD块,而不仅仅是提供exports
和define
变量,所以它现在将传单代码编译成这样:
(function (global, factory) {
true ? factory(exports) :
0;
}(this, (function (exports) { 'use strict';
[...]
})));