如何使webpack编译 node_modules 中的 npm 包
What
在项目开发过程中,我们会使用到大量第三方的npm包,这些包大部分使用了 es中新的语法编写 ,但是在发布的时候,它们有些是经过 babel,tsc, esbuild 等工具转换后发布的,有的则没有转换直接发布到 npm 中,
所以当我们在 webpack 中使用这样的包时,可能会看到如下报错:
Why
上面的截图中使用了一个叫 screenfull 的包,点进去一看,原来是代码中使用了?.
运算符,而在 webpack.config.js 中,由于 exclude 被设置为整个 node_modules, 从而使 babel 跳过了对 screenfull 的转换:
module: {
rules: [
{
test: /\.(?:js|mjs|cjs)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "defaults" }]
]
}
}
}
]
}
How
这时,我们需要修改 exclude 的配置,确保报错的 npm 中的包的代码被转换。exclude,include 作为一个 Condition, 可以是下面的形式:
- 字符串:匹配输入必须以提供的字符串开始。是的。目录绝对路径或文件绝对路径。
- 正则表达式:test 输入值,如
/node_modules/
。 - 函数:调用输入的函数,必须返回一个真值(truthy value)以匹配。
- 条件数组:至少满足一个匹配条件, 如
[/node_modules/, /lib/]
- 对象:所有属性对应的 condition 都要满足。每个属性都有一个定义行为。
所以上面的问题可以这样来配置:
module: {
rules: [
{
test: /\.(?:js|mjs|cjs)$/,
+ exclude: {and: [/node_modules/], not: [/screenfull/] }, //screenfull是报错的npm 包
- exclude: /node_modules/,
}
]
}
除此以外,我们也可以定义一个condition函数,来完成同样的功能:
module: {
rules: [
{
test: /\.(?:js|mjs|cjs)$/,
exclude: (filepath) => {
if (/node_modules/.test(filepath)) {
if (/screenfull/.test(filepath)) {
return false;
}
return true;
}
return false
}
}
]
}
cnblogs-md-editor编辑器,用Markdown写博客就用它