移動端除錯不是總能 inspect 一通的,為此我們引入了騰訊的萬金油
vConsole
。開發時固然蛋定,釋出時卻有點操蛋。
開始的使用
通過判斷是否為 dev 環境,載入 vConsole
並例項化使用:
// 開發時引入 vConsole
if (process.env.NODE_ENV === 'development') {
// 吐槽一波:不支援 import 方式
const VConsole = require('vconsole');
new VConsole();
}
複製程式碼
生產環境是沒有 vConsole
了吧!想象很豐滿,打包很骨感。
如果你 splitChunks
了的話,打包後的檔案多出了個 vConsole
,約 90k。使用 webpack-bundle-analyzer
分析也會看到多出一大塊。。。
在這個移動端分秒必爭的時代,凡是能從程式碼層面上優化的沒理由不做。
> 每次合併到主分支時註釋再提交,像下面這樣[笑哭]
// 開發時引入 vConsole
// if (process.env.NODE_ENV === 'development') {
// // 吐槽一波:不支援 import 方式
// const VConsole = require('vconsole');
// new VConsole();
// }
> 每次開發時再去掉註釋,丟你煤泥~
複製程式碼
碼·格瓦拉:“優化是不可能不優化的,這輩子都不可能不優化的。”
定義瀏覽器端環境變數
啟動時 NODE_ENV=development webapck
這樣定義的環境變數只在 node 執行 webpack
時生效,通過 process.env
訪問。簡而言之,只能在 webpack.config.js
中判斷 dev/prod。
所以實現之前的程式碼邏輯我們需要 DefinePlugin
。使用時:
// webpack.config.js
const webpack = require('webpack');
module.exports ={
plugins: [
new webpack.DefinePlugin({
__DEV__: JSON.stringify(false),
}),
],
};
複製程式碼
引入 vConsole
的方式基本不變:
// index.js
// __DEV__ 就是 DefinePlugin 注入的全域性常量
// 開發時引入 vConsole
if (__DEV__) {
// 吐槽一波:不支援 import 方式
const VConsole = require('vconsole');
new VConsole();
}
// 打包後的程式碼長這樣:
// 看起來這外掛就是執行文字替換的功能
if (false) {
// 吐槽一波:不支援 import 方式
const VConsole = require('vconsole');
new VConsole();
}
複製程式碼
程式碼邏輯實現了,但是 vConsole
依舊在打包檔案裡。這時候就要藉助我們功能強大的程式碼壓縮。
程式碼壓縮
webpack v4 版本設定為 mode: 'production'
後預設即啟用程式碼壓縮。
以前推薦的是 UglifyjsWebpackPlugin
,底層 uglify-js
,但是隻支援 ES5,所以倉庫上還有個 harmony
分支用來處理 ES6,webpack 外掛用的也是這個分支。但是這個分支已經長時間沒人維護了,所以官方轉到另一個 TerserWebpackPlugin
,兩個外掛基本一模一樣。
手動啟用:
module.exports = {
optimization: {
minimize: true
},
};
// 或者直接覆蓋自帶的,可進行顆粒度的控制
const TerserWebpackPlugin = require('terser-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new TerserWebpackPlugin({
terserOptions: {
compress: {
dead_code: true, // 預設。刪除不可到達的程式碼
},
},
});
],
},
};
複製程式碼
而我們需要的就是其刪除 dead code 功能,類似下面這樣的就是 dead code:
----------------------------
| if (false) alert('你好'); | // 一塊 dead code
----------------------------
複製程式碼
實際使用可能需要進行判斷,但是有點坑。
statement | dead_code 支援 |
---|---|
true /false |
✓ |
1 === 2 |
✓ |
'a' !== 'a' |
✓ |
'a' !== 'b' |
✗ |
undefined /null |
✗ |
- Boolean/Number 支援可寫表示式判斷
- String 只支援完全相同的兩字串判斷,不同字串不支援
- Undefined/Null 不支援
最後
使用 DefinePlugin
+ TerserWebpackPlugin
配置,打包後發現 vConsole
沒了。可以向老闆申請加雞腿了······
小貼士:ProvidePlugin
與 externals
的區別,前者自動 import
,後者是無需 npm install
即可直接 import
。