背景
最近在做公司内部的小程序脚手架,为了兼容老项目和旧项目,做了vue2+taro,vue3+taro两个模板,发现terser-webpack-plugin在vue2和vue3中的使用方式并不相同,同样的配置在vue3+webpack5中生效,但是在vue2+webpack4中就不生效
vue3模板的解决办法在taro小程序terser-webpack-plugin插件不生效 已经做了说明,本文主要介绍在vue2+webpack4中的解决办法。
遇到的问题
首先说明下前提,关于微信小程序,我在package.json里面配置了四个命令,如下:
json
"build:weapp": "taro build --type weapp", //生产环境
"prod:weapp": "cross-env NODE_ENV=production npm run build:weapp -- --watch", //生产环境热编译
"dev:build:weapp": "cross-env NODE_ENV=development npm run build:weapp", //测试环境非热编译
"dev:weapp": "cross-env NODE_ENV=development npm run build:weapp -- --watch", //测试环境热编译
通过查看taro源码已经知道在生产环境的时候,源码里面会自动使用压缩
所以只需要在测试环境的时候做配置即可,接着按照官网做了以下配置
js
// config/dev.js
module.exports = {
mini: {
webpackChain: (chain, webpack) => {
chain.merge({
plugin: {
install: {
plugin: require('terser-webpack-plugin'),
args: [
{
terserOptions: {
compress: true, // 默认使用terser压缩
keep_classnames: true, // 不改变class名称
keep_fnames: true, // 不改变函数名称
},
},
],
},
},
})
},
},
}
运行
bash
npm run dev:weapp
发现确实起到了压缩效果,demo编译后的体积由836kb变成了334kb
以为到这一步就大功告成啦,no,no,no,才刚刚开始~,哈哈哈哈,接下来意想不到的发生啦...
当然如果你不需要配置dev:build:weapp这条命令,当我没说...
运行
bash
npm run dev:build:weapp
发现并没有打包成功,提示这个文件和已有的文件冲突
然后开始排查错误,看了文档中附的这个链接《编写插件,将 Taro 编译打包耗时缩短至三分之一》。
删除前面的配置,按照这个文档进行配置(不做详细介绍,文档里面都有),发现报如下错误:
在minifyMainPackage.js里面打印minimizers,发现已经存在terser插件,如果再创建就会报错
js
//minifyMainPackage.js
const TerserPlugin = require('terser-webpack-plugin')
module.exports = (ctx) => {
ctx.modifyWebpackChain(args => {
const chain = args.chain
const minimizers = chain.optimization.get('minimizer') || []
console.log(minimizers,'==minimizers')
.....
})
}
此时运行如下,却发现并不会报错
bash
npm run dev:weapp
但是minimizers打印出来的是[]
由此可以看出,dev:build:weapp的时候terser已经存在无需重新添加,但是dev:weapp的时候terser却不存在。
结合源码,然后开始各种排查,发现dev:build:weapp的时候虽然打印process.env.NODE_ENV出来的是development,进入的是dev.js里面的逻辑,但是在taro内部还是按照 production 添加了terser-webpack-plugin插件,再次添加就会报错。
因此在minifyMainPackage.js加了一个判断,判断插件存在就不再创建
附上完整代码
js
//minifyMainPackage.js
const TerserPlugin = require('terser-webpack-plugin')
module.exports = (ctx) => {
ctx.modifyWebpackChain(args => {
const chain = args.chain
const minimizers = chain.optimization.get('minimizer') || []
// 检查是否已存在TerserPlugin实例,避免重复添加
const hasTerser = minimizers.some(minimizer => {
return minimizer.constructor.name === 'TerserPlugin'
})
//没有则创建
if(!hasTerser){
chain.optimization.minimize(true)
chain.merge({
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.(?:[js]sx?|mjs)$/, // 一般匹配JavaScript和JSX文件,根据需要调整
parallel: true,
minify: TerserPlugin.swcMinify,
cache: true,
extractComments: true,
sourceMap: true,
terserOptions: {
parse: {
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
arrows: false,
collapse_vars: false,
comparisons: false,
computed_props: false,
hoist_funs: false,
hoist_props: false,
hoist_vars: false,
inline: false,
loops: false,
negate_iife: false,
properties: false,
reduce_funcs: false,
reduce_vars: false,
switches: false,
toplevel: false,
typeofs: false,
booleans: true,
if_return: true,
sequences: true,
unused: true,
conditionals: true,
dead_code: true,
evaluate: true,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
},
}),
],
},
})
}
})
}
然后在dev.js进行引入
js
const path = require('path')
module.exports = {
env: {
NODE_ENV: '"development"'
},
defineConstants: {
},
plugins: [ path.resolve(__dirname, './minifyMainPackage.js')],
mini: {
},
h5: {
}
}
}
对啦,记得安装插件呀~
bash
npm install -D terser-webpack-plugin@3.0.5
大功告成啦~
完结,撒花