babel-loader配置里的 include、exclude

10,600 阅读2分钟

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 的优先级问题

经过一系列验证(不是一句话能说的完的),得出以下结论: **

  1. include 与 exclude 只影响 loader 是否对test 属性匹配的文件进行 transpile,不影响 webpack 进行打包(依旧会生成 bundle.js)
  2. 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。

0x03 参考