一、前言
本文为针对微信小程序发布过程中提示的"以下文件体积超过500KB,已经跳过压缩以及ES6转ES5处理,如在该文件有使用到ES6特性,请使用其它工具转换成ES5或压缩,否则可能会在低版本设备上运行有风险:. static/js/vendorjs"
使用到的技术栈:
- 1.mpvue [mpvue.com/]
- 2.webpack [www.webpackjs.com/]
二、问题描述
使用mpvue小程序开发打包发布上传时,会出现以下的报错:
或者在进行真机预览时出现代码上限警告出错提示: 前者在mpvue issue中有人提类似问题,答复是可以不用理会,不影响上传,笔者亲自试过,确实只是提示性错误,最终代码还是能上传并且可以正常运行,这个问题也不大,但后者,因为我们的小程序经常会有用到使用真机调试的情况,因此,这种报错情况不解决,会对开发时真机模拟造成很大困扰。既然问题来了,需求明确,我们看下如何解决。三、问题分析
1.分析vendor.js
依据错误提示,打开工程dist目录下/static/js/vendor.js,可以发现这是一个公共包,如果在多个页面或者模块使用到有相关的代码,那么该代码会被Webpack识别为公共代码,公共代码都会被抽离到这里来,从保留的注释,我们大概能知道哪些内容是公共部份。
再回到业务逻辑代码,搜索类似的关键字,可以发现,产生这类问题的根源基本上是我们的业务逻辑代码中在不经意或者需要时引入了过多的第三方包,例如类似下图的代码模拟:2.分析打包依赖(webpack-bundle-analyzer)
安装依赖
在工程build
目录的webpack.dev.conf.js
配置文件中添加分析配置,关键代码如下:
这里将分析结果访问端口设置为9800,设置完成启动后命令行有相应的输出,点击链接可访问。
然后,可以得到类似如下的分析报告,这里要注意,选择Stat
按钮
3.分析打包配置
回到webpack打包配置部份,找到公共代码抽离部份,可以发现CommonChunkPlugin
(因该工程使用的是mpvue相对较旧的之前版本,对应的webpack使用的是CommonChunkPlugin)
CommonsChunkPlugin主要是用来提取第三方库和公共模块,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大,从而导致加载时间过长
这里抽取的是第三方公共包部份。
注:webpack4之前使用的是webpack.optimize.CommonsChunkPlugin,之后则是使用config.optimization.splitChunk来进行公共代码抽离
四、解决方案
1.改造webpack进行拆包处理
通过分析工程,以本工程为例,可以发现在分析报告中占据大块面积的包模块主要集中在划红线部份:
(包模块占的面积越大,说明其打包体积越大)2.进一步拆包
步骤一:
上图所示的内容将会被统一打包入Vendor.js,在不改变业务逻辑,例如删除无用引用等情况下,需要对Vendor.js打包内容进一步拆分。
方法就是:建多一个CommonsChunkPlugin对Vendor.js里边的内容,依据匹配列表进行二次拆分。
chunks:['vendor'] 显式指定要拆分的模块
name:'commons' 指定拆分后生成的新模块名
拆分规则:则依据module.resource返回的模块名作匹配判断,在minChunks自定义拆分函数中作相应的处理,当结果返回true,webpack则会认为该部份需要进一步抽离, 这里忽略count:引用次数,结果是只要有引用则抽离。
步骤二:
上一步骤解决了webpack配置问题,会生成多一个叫commons.js的公共包,但还需解决另一个问题,打包文件对该文件的引用。
文件引用的关键代码在node_modules/mpvue-loader/lib/mp-compiler/templates.js
我们需要对该文件进行改造:
这里有个问题:mpvue-loader是官方维护的,这里的改动是本地的module_modules目录,那么在团队合作时,其它人只要重新安装包,岂不是又被覆盖了? 所以,我们引入了以下几中方案当中的第3种:
1.将mpvue-loader拷出来放入工程目录单独维护
2.将mpvue-loader拷一份,放入内部私服维护
3.编写单独脚本,生成引用,在打包启动命令中引用
综合考虑,我们选择第3种方案,首先需要:
建立引用改造文件check-vendor.js
打包时先执行覆盖文件,再执行打包命令
这样就确保每次打包时会动态插入新引用的commons.js文件配置script入口
3.其它方案
通过翻阅其它资料,还有其它方案,比如:
小程序分包
但因考虑到工程业务尽量不更改,新旧版本兼容等问题,这里采用了自行修改webpack打包机制方案,尽量做到对业务逻辑代码影响最小。
4.按需导入
还有一种方案,就是需要分析业务逻辑代码中有些包是否可以只导入需要的部份,例如i18,依据业务判断是否需要那么多的语言包之类,等等,例如以下介绍的方法:
Webpack优化技巧,构建效率提升50%
五、优化结果
通过以上的一系列步骤优化,最终对比如下:
优化打包前:
优化打包后:
最终效果:正常上传,错误提示消失,真机调试可正常进行。
六、总结
1.旧工程改造思考
通过以上分析和解决步骤,考虑到工程是否适合升级新版本mpvue,对现有业务逻辑影响有多大等评估,最终我们选择了不动业务逻辑,改造webpack的方式进行。如果风险不太大,建议可考虑小程序分包方案。
2.后续兼容,锁包处理
考虑到mpvue升级兼容等问题,把package.json相关依赖固化在某一版本,因此去除所有^符号,保留~或者不保留该符号,相对稳定地来处理版本升级的兼容问题。最简示例DEMO已上传到Github:
mp-compress
有需要的朋友欢迎参考。