记一次webpack构建报错

2022-06-06 16:32:13 浏览数 (1)

五一结束,开开心心的上班,结果第一天就给了一个惊喜,原本webpack构建好好地,突然就报了一个错。

错误日志如下

代码语言:javascript复制
Can't import the named export 'SetArray' from non EcmaScript module (only default export is available

详细错误日志如下

代码语言:javascript复制
[Build] [BABEL] Note: The code generator has deoptimised the styling of /data/auto-ci/wspace/node_modules/lodash/lodash.js as it exceeds the max of 500KB.
[Build] ./node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs 38:20-28
[Build] Can't import the named export 'SetArray' from non EcmaScript module (only default export is available)
[Build]     at HarmonyImportSpecifierDependency._getErrors (/data/auto-ci/wspace/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:88:6)
[Build]     at HarmonyImportSpecifierDependency.getErrors (/data/auto-ci/wspace/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js:68:16)
[Build]     at Compilation.reportDependencyErrorsAndWarnings (/data/auto-ci/wspace/node_modules/webpack/lib/Compilation.js:1463:22)
[Build]     at /data/auto-ci/wspace/node_modules/webpack/lib/Compilation.js:1258:10
[Build]     at AsyncSeriesHook.eval [as callAsync] (eval at create (/data/auto-ci/wspace/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:22:1)
[Build]     at AsyncSeriesHook.lazyCompileHook (/data/auto-ci/wspace/node_modules/tapable/lib/Hook.js:154:20)
[Build]     at Compilation.finish (/data/auto-ci/wspace/node_modules/webpack/lib/Compilation.js:1253:28)
[Build]     at /data/auto-ci/wspace/node_modules/webpack/lib/Compiler.js:672:17
[Build]     at _done (eval at create (/data/auto-ci/wspace/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)
[Build]     at eval (eval at create (/data/auto-ci/wspace/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:30:22)
[Build]     at /data/auto-ci/wspace/node_modules/webpack/lib/Compilation.js:1185:12
[Build]     at /data/auto-ci/wspace/node_modules/webpack/lib/Compilation.js:1097:9
[Build]     at processTicksAndRejections (internal/process/task_queues.js:79:11)
[Build]  @ ./node_modules/@babel/generator/lib/source-map.js
[Build]  @ ./node_modules/@babel/generator/lib/index.js

源码分析

经过一番测试大致锁定了报错范围。

直接报错的位置在 @jridgewell/gen-mapping 这个包,这个包在引入@jridgewell/set-array 而上面错误的详细信息也可以看出就是 Can't import the named export 'SetArray' from non EcmaScript module (only default export is available) 大致意思就是无法导出 SetArray 这个模块。

于是github上找到这两个包的源码

代码语言:javascript复制
// @jridgewell/gen-maping/dist/gen-mapping.mjs
import { SetArray, put } from '@jridgewell/set-array';
代码语言:javascript复制
// @jridgewell/set-array/dist/set-array.mjs
class SetArray {
  constructor() {
    this._indexes = { __proto__: null };
    this.array = [];
  }
}

检查了源码发现并没有什么问题,都是es6的正常语法,至此,似乎没办法往下查了。

重新分析

既然看源码看不出来,那么就从另一个角度来分析一下。

代码语言:javascript复制
本地构建正常,服务端构建机报错,项目并没有锁定
这个项目并没有使用 package-lock.json 锁定包版本。

难道是因为 node_modules 的某个依赖包偷偷更新了? 有很大可能是这样。

要验证上面的问题也很简单,直接删掉本地node_modules,重新npm i安装所有依赖。 果然,重新安装复现了问题了,那么基本就锁定了是版本问题了。 同时也发现了@jridgewell/set-array这个包是个新包,@jridgewell/gen-mapping也是最近才引入@jridgewell/set-array包的。

分析了node_modules内部的互相依赖关系,发现 @babel/* 系列的npm包依赖了@jridgewell/gen-mapping。 那么很大可能是最近 @babel/* 更新导致的了。

验证猜想

为了验证这个这个猜想,我将package.json 里面所有的@babel/* 包的“^”都去掉(固定版本,不自动安装新包)

代码语言:javascript复制
"@babel/******": "^7.10.2"
=>
"@babel/******": "7.10.2"

很幸运,固定@babel/** 系列的版本之后能正常编译了,这个猜想正确了。

解决问题

既然知道原因了,那么解决办法也就有了 直接修改babel相关所有依赖包版本、或者加入package-lock.json? 可以解决,但是经过仔细考虑,最终还是放弃了上面的办法。 原因是:似乎上面的代码并没有什么问题,但是确实又在构建引入 SetArray 模块的时候报错了。 那么会不会是构建的问题呢?构建不支持这个 .mjs 后缀的文件?

经过搜索,网上最近也有很多人遇到这个问题,其中一个解决办法让我似乎明白了问题原因了

代码语言:javascript复制
const config = {
  module: {
    // ...
    rules: [
      // ...
      {
        include: /node_modules/,
        test: /.mjs$/,
        type: 'javascript/auto'
      }]
  }
}

将上面的配置配置之后,果然不再报错了。 搜了下 javascript/auto找到如下结果

这个图上说的应该就是原因了,虽然他说的是json文件,但是对于mjs应该也是同样的道理。

至此,问题解决,核心关键就在于配置mjs文件的构建 rule 类型为 javascript/auto

.mjs 是 nodejs 能识别的文件后缀,直接构建到项目中在前端浏览器是不能直接跑的,因此需要打包转义。

0 人点赞