Webpack4支持打包第三方库quickjs-emscripten
解释ESM模块出错
编译quickjs-emscripten
时, 会出现以下错误:
error in ./node_modules/quickjs-emscripten-core/dist/index.mjs
Module parse failed: Unexpected token (1:731)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> import{a as O,b as A,c as Q}from"./chunk-QM66IUK3.mjs";.......
这个错误说明webpack无法正确解析模块的语法, 一般vue-cli
的生成的工程都有配置.mjs
的解析, 可通过导出配置文件查看:
npx vue-cli-service inspect > webpack-config.js
通过搜索大致可以发现.mjs
的相关配置
/* config.module.rule('mjs') */
{
test: /\.mjs$/,
type: 'javascript/auto',
include: [
/node_modules/
]
},
明明配置了但是还是解释不了, 怎么办? 所幸的是, 可以通过babel
来转换一下. 生成的工程里其实也已经包含了babel, 所以可以直接拿来用. 以下配置参考如下:
// vue.config.js
module.exports = {
...
chainWebpack: config => {
config.module
.rule('quickjs')
.before('mjs') // 加在mjs的规则之前
.test(/quickjs.+\.mjs$/)
.use('cache')
.loader('cache-loader')
.end()
.use('babel')
.loader('babel-loader')
.options({
presets: [
['@babel/preset-env', { targets: "defaults" }]
]
})
.end()
}
}
再次编译后, webpack就能正确解释quickjs-emscripten
里的模块了. But.....
找不到模块?
解释错误是没有了, 但是仍然提示有错误:
ERROR Failed to compile with 1 error
This dependency was not found:
* @jitl/quickjs-wasmfile-release-sync/emscripten-module in ./node_modules/@jitl/quickjs-wasmfile-release-sync/dist/index.mjs
难道是没安装相应的模块? 但是通过查找node_modules
, 是有@jitl/quickjs-wasmfile-release-sync
这个文件夹的. What the hell? 这个原因着实搞不懂...
于是我新生一计, 通过alias
指定不就好了:P
configureWebpack: {
resolve: {
alias: {
'@jitl/quickjs-wasmfile-release-sync/emscripten-module': path.resolve(__dirname, 'node_modules/@jitl/quickjs-wasmfile-release-sync/dist/emscripten-module.browser.mjs')
}
},
}
这个问题也解决了, But......
不支持import.meta.url
由于quickjs-emscripten
使用了ESM新特性import.meta.url
. Webpack4是不支持且直接抛出以下异常:
error in ./node_modules/@jitl/quickjs-wasmfile-release-sync/dist/emscripten-module.browser.mjs
Module parse failed: Unexpected token (18:25)
File was processed with these loaders:
* ./node_modules/cache-loader/dist/cjs.js
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| import "core-js/modules/web.url-search-params.size.js";
| var QuickJSRaw = (() => {
> var _scriptDir = import.meta.url;
OMG! 难道只能换webpack5或者vite? 这可是伤筋动骨啊... 难道没有其他办法了?
THANKFULLY, 我们不是已经用alias指向某个.mjs文件了吗? 改成我们本地的某个文件不就好了? 只要不使用import.meta.url
, 一切都好说!
最后按照这个思路改造了一下, 终于是能正确运行了...
还要再说几句
这个又是折腾的一天... 明明都一把年纪了, 而且都2024年了, 还要去折腾这些蛋疼的工程配置, 真的烦. 不过谁让我们的工程这么老旧呢, webpack4就算了, package-lock.json还是version1的(node14安装的版本), 以后还有得折腾, 要是有个给力点的人帮我做这种事情就好了...
另外工程里的jest
还不能运行依赖quickjs-emscripten
的单元测试, 理由是不支持dynamic import
. 然后我看其本身也是用vitest
进行单元测试的, 好吧也只能用vitest
了. 而vitest
从1.0后就要用node18+
才能跑, 我们的项目还是node14, 只能望着涩涩发抖.
不过我现在已经成功集成并且跑了不少关于插件的测试用例啦, 在这里也小小祈祷一下公司有朝一日能用上吧:)