前言
roadhog 在打包单页应用文件的时候如果采取异步加载模块文件的话,每个模块里面应用到的一些公用库(antd、moment等)会在每个生成的异步模块文件里面重复应用到,导致所有文件的总体积增加了很多(因为公用库被重复引用了)本文描述的是如何解决这个问题
问题描述
在 cpbs PC 端开发过程中,发现在经过 roadhog build --debug --analyze
命令打包之后的文件体积很大,具体内容如下所示:
1 | Compiled successfully in 25.6s. |
roadhog 将每个 model 都打包为一个单独的异步调用的 js 文件,这些文件即使在 gzip 压缩之后每个都需要平均 1M 的体积,在查看打包的具体内容 (stats.html
)之后,发现体积过大的这些包都对一些共同使用到的组件进行了打包,而非引用模块部分的代码体积只有 300k 左右:
经过分析,发现体积过大的原因有以下几点:
moment
模块被重复引用moment
模块引用了多余的本地化文件(约300k)antd
重复引用到的模块,如Table
、Button
、Form
等被各个模块重复打包,增加了体积
解决思路
- 将体积大的公用的模块进行打包(
moment
、antd
部分使用频率高的模块) - 移除
moment
模块没有使用到的语言包
本文只讲述如何将公共模块抽离出来作为一个单独文件
解决过程
使用 CommonsChunkPlugin
将公用模块抽离到 ventor.js
修改 roadhog
的配置文件:
1 | // .roadhogrc.js |
在根目录添加 webpack.config.js
,输入以下内容:
1 | const webpack = require('webpack') |
至此,完成了将除 antd
之外的公用模块的抽离
使用 CommonsChunkPlugin
将 antd
的高频模块抽离到 antd.js
修改 webpack.config.js
为:
1 | const webpack = require('webpack') |
修改 index.html
为 index.ejs
将 /src
目录下的文件进行如下调整:
1 | |-index.ejs |
各个文件的配置为:
1 | <!-- index.ejs --> |
1 | import 'babel-polyfill' |
index.less
和 router.js
的内容这里不赘述
经过以上配置之后,index.ejs 能够根据 roadhog
里面的 entry
配置自动引入所有入口文件。
注意 CommonsChunkPlugin
配置里面的 name
的数组顺序会影响到 entry 的引用顺序,如果出现 webpack
未定义的错误,尝试改变这个属性值的顺序,因为 CommonsChunkPlugin
是按照抽离顺序将 webpack
的全局对象放到了 entry
的最后一个入口文件里面。
解决成果
经过上面的处理之后,打包的个文件体积为:
1 | Compiled successfully in 21.1s. |
可以看到被抽离了公用模块之后的各模块的体积基本减少到了 500k(具体抽离哪些模块还可以再精准研究),代码包的整体面积无疑是减少了很多的。
后续报道
发现在使用多入口方式的时候无法触发热更新,所以在开发环境之下还是使用旧有的打包方式,只在线上环境使用抽离式打包,解决方式就是在 webpack.config.js
里面添加一个环境变量判断,详细见上面代码。
1 | const webpack = require('webpack') |