手头做的项目开发得差不多了, 而打包配置是一开始粗略配置的, 不大的项目打包出来得 6MB+, 所以现在必须进行优化
打包结果分析
执行命令
webpack --profile --json > stats.json
, 可以将打包过程的详细信息以 json 格式记录到文件中依据该文件, webpack-bundle-analyzerWebpack Chart 等分析工具会以可视化的形式展示打包过程和结果
如果不想用这些额外工具, 通过命令
webpack --display-modules --sort-modules-by size
,webpack 会在日志中按大小排序显示所有模块
我在项目中, 将第三方库基本都集中打包到一个 chunk (vendors), 业务逻辑单独一个 chunk (app)打包总体积的大头来自 vendors, 其中 antd 占据大头(3MB+)moment 占据约 500KB 提取的 CSS 约 300KBreact-dom 也是 500KB+, 出乎意料的是 lodash 也是 500KB+
逐个击破
设置环境变量 NODE_ENV 为 production
不少库会按开发环境 (development) 和生产环境 (production) 提供不同的文件, 主要是为了开发模式下的调试, 也会因此有文件体积上的差别用于生产环境的打包, 设置其为 production 后, 这些库会提供最小体积的文件
- plugins: [
- // ...
- new webpack.DefinePlugin({
- 'process.env': {
- NODE_ENV: JSON.stringify('production')
- }
- }),
- // ...
- ]
- css-loader
css-loader 在 webpack 默认不开启压缩, 需要设置 css-loader?minimize
- module: {
- // ...
- {
- test: /\.css$/,
- use: ExtractTextPlugin.extract({
- fallback: 'style-loader',
- use: 'css-loader?minimize'
- })
- }
- // ...
- }
大头 antd (ant design)
因为并没有使用 antd 的所有组件, 所以按需加载是必需的根据其文档(按需加载 - Ant Design), 需要安装 bable 插件 babel-plugin-import, 并在 babel 配置中添加:
- {
- // ...
- "plugins": [
- ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }],
- // ...
- ]
- }
在我配置过程中, libraryDirectory 配置的不同也会有较大影响, 但按目前文档来看貌似没有影响, 待我确认后再做记录
=== 2018-02-23 更新 ===
看来 bable-plugin-import 这几天有更新, 现在配置项 libraryDirectory 的默认值时 lib, 即使用通过 require (commonjs) 引用模块的文件而先前我在配置的时候并没有默认值, 如果没有显示配置 libraryDirectory, 打包结果会出现重复的内容
采用了 es6 module 的项目建议配置 libraryDirectory 为 es, 即使用通过 import (es6 module) 引用模块的文件这种情况打包后的体积要更小一些
=== end ===
这里还有很重要一点, babel-plugin-import 要求 antd 不能被提取为公共模块 vendors, 否则就无法实现按需加载尚不清楚是 babel 插件的原因, 还是这个插件单独的原因
moment
moment 库的体积开销主要是 i18n 文件, 配置 webpack 将用不到 i18n 文件不打包即可
- plugins: [
- new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /zh-cn/),
- ]
看上去很轻量的 lodash
lodash 看上去就是一些工具函数, 应该是很轻量的, 然而一次全部加载下来要达到 500KB, 因此也需要按需加载它的按需加载还比较麻烦
lodash 为每个方法单独提供了库, 但这种方式在实际使用中并不灵活, 所以这种最干净的方法不建议使用
像 antd 一样, lodash 也有 babel 插件用于按需加载 babel-plugin-lodash
- {
- // ...
- "plugins": [
- "lodash",
- // ...
- ]
- }
同样, lodash 就不能提取到公共模块了
最后
打包结果的体积开销主要就是以上几项经过优化后, 体积下降至 1.5MB 以内, 还是很客观的不过 antd 依然占据大头, 后续会考虑把 antd 替换掉, 毕竟用到的组件不多
来源: https://segmentfault.com/a/1190000013326506