手頭作的項目開發得差很少了,而打包配置是一開始粗略配置的,不大的項目打包出來得6MB+,因此如今必須進行優化。javascript
執行命令 webpack --profile --json > stats.json
,能夠將打包過程的詳細信息以 json 格式記錄到文件中。依據該文件,webpack-bundle-analyzer、Webpack Chart 等分析工具會以可視化的形式展現打包過程和結果。css
若是不想用這些額外工具,經過命令 webpack --display-modules --sort-modules-by size
,webpack 會在日誌中按大小排序顯示全部模塊。java
我在項目中,將第三方庫基本都集中打包到一個 chunk (vendors),業務邏輯單獨一個 chunk (app)。打包整體積的大頭來自 vendors,其中antd
佔據大頭(3MB+)、moment
佔據約500KB、提取的 css 約300KB、react-dom
也是500KB+,出乎意料的是 lodash
也是500KB+。react
NODE_ENV
爲 production
很多庫會按開發環境(development)和生產環境(production)提供不一樣的文件,主要是爲了開發模式下的調試,也會所以有文件體積上的差異。用於生產環境的打包,設置其爲production
後,這些庫會提供最小體積的文件。webpack
plugins: [ // ... new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } }), // ... ]
css-loader 在 webpack 默認不開啓壓縮,須要設置 css-loader?minimize
。git
module: { // ... { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader?minimize' }) } // ... }
由於並無使用 antd 的全部組件,因此按需加載是必需的。根據其文檔(按需加載 - Ant Design),須要安裝 bable 插件 babel-plugin-import
,並在 babel 配置中添加:es6
{ // ... "plugins": [ ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }], // ... ] }
在我配置過程當中,libraryDirectory
配置的不一樣也會有較大影響,但按目前文檔來看貌似沒有影響,待我確認後再作記錄。github
=== 2018-02-23 更新 ===web
看來bable-plugin-import
這幾天有更新,如今配置項 libraryDirectory
的默認值時 lib
,即便用經過 require
(commonjs) 引用模塊的文件。而先前我在配置的時候並無默認值,若是沒有顯示配置 libraryDirectory
,打包結果會出現重複的內容。json
採用了 es6 module 的項目建議配置 libraryDirectory
爲 es
,即便用經過 import
(es6 module) 引用模塊的文件。這種狀況打包後的體積要更小一些。
=== end ===
這裏還有很重要一點,babel-plugin-import
要求 antd
不能被提取爲公共模塊 vendors,不然就沒法實現按需加載。尚不清楚是 babel 插件的緣由,仍是這個插件單獨的緣由。
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 替換掉,畢竟用到的組件很少。