0x01 问题引出
今天审查之前的一个基于 webpack 进行构建的项目,发现项目编译最后总是会出现几个错误:
通过错误提示可以看出,UglifyJs 在处理 webpack 构建的 js 文件时出错。导致出错的原因就是这三个 js 文件里存在 es6代码,而 UglifyJs 只能处理 ECMAScript 5代码。进入原文件(invoiceStep1.6096d01d1b807ad3cab2.min.js:509,68)可以发现代码如下:
// CONCATENATED MODULE: ./node_modules/yb-tool/lib/date/format.js
/* harmony default export */ var date_format = (function (date, fmt = 'YYYY-MM-DD HH:mm:ss') {
if (!date) {
return ''
}
发现问题的根源就是该项目依赖了 yb-tool 工具库,而该工具库使用 es6 编写。 再看下此时的 babel-loader 配置:
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [
path.resolve(__dirname,'../src')
],
exclude: /node_modules/
}
为了提高构建效率,之前为 babel-loader 设置了 exclude: /node_modules/
,这就导致了 yb-tool 里的源码不会编译。那么现在设置
include: path.resolve(__dirname,'../node_modules/yb-tool')
是不是就可以了?
0x02 探索过程
将node_modules/yb-tool添加到 include之后, babel-loader的配置如下:
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [
path.resolve(__dirname,'../src'),
path.resolve(__dirname,'../node_modules/yb-tool')
],
exclude: /node_modules/
}
再次运行项目发现还是会报跟之前一样的错误💔。那问题出在哪里呢?
我没搞清楚:include 与 exclude 的优先级问题。
经过一系列验证(不是一句话能说的完的),得出以下结论: **
- include 与 exclude 只影响 loader 是否对test 属性匹配的文件进行 transpile,不影响 webpack 进行打包(依旧会生成 bundle.js)
- exclude 权重更高,exclue 会覆盖 include 里的配置。如果设置了 include: 'app'和 exclude:'app',那么include:'app'不会生效,即 app 文件夹里文件都不会被 babel-loader处理。
基于以上结论,正确的配置如下:
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory',
include: [
path.resolve(__dirname,'../src'),
path.resolve(__dirname,'../node_modules/yb-tool')
],
// exclude: /node_modules/
}
这样就能实现:除了 yb-tool 其它 node_modules 目录里的代码都不会被 babel-loader 处理。(当然还有其它方式,exclude 后边的条件可以是函数,也可以通过在函数里排除 yb-tool 目录来实现需求)。
webpack 里几乎所有 loader 都支持 include 和 exclude 属性,本文虽然是基于 babel-loader举例,但以上结论一样适用于其它 loader。