把你的devtools從webpack裏刪除

移動端調試不是總能 inspect 一通的,爲此咱們引入了騰訊的萬金油 vConsole。開發時當然蛋定,發佈時卻有點操蛋。node

開始的使用

經過判斷是否爲 dev 環境,加載 vConsole 並實例化使用:webpack

// 開發時引入 vConsole
if (process.env.NODE_ENV === 'development') {
  // 吐槽一波:不支持 import 方式
  const VConsole = require('vconsole');
  new VConsole();
}
複製代碼

生產環境是沒有 vConsole 了吧!想象很豐滿,打包很骨感。git

若是你 splitChunks 了的話,打包後的文件多出了個 vConsole,約 90k。使用 webpack-bundle-analyzer 分析也會看到多出一大塊。。。github

在這個移動端分秒必爭的時代,凡是能從代碼層面上優化的沒理由不作。web

> 每次合併到主分支時註釋再提交,像下面這樣[笑哭]

// 開發時引入 vConsole
// if (process.env.NODE_ENV === 'development') {
// // 吐槽一波:不支持 import 方式
// const VConsole = require('vconsole');
// new VConsole();
// }

> 每次開發時再去掉註釋,丟你煤泥~
複製代碼

碼·格瓦拉:「優化是不可能不優化的,這輩子都不可能不優化的。」npm

定義瀏覽器端環境變量

啓動時 NODE_ENV=development webapck 這樣定義的環境變量只在 node 執行 webpack 時生效,經過 process.env 訪問。簡而言之,只能在 webpack.config.js 中判斷 dev/prod。segmentfault

因此實現以前的代碼邏輯咱們須要 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 依舊在打包文件裏。這時候就要藉助咱們功能強大的代碼壓縮。ide

代碼壓縮

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
  1. Boolean/Number 支持可寫表達式判斷
  2. String 只支持徹底相同的兩字符串判斷,不一樣字符串不支持
  3. Undefined/Null 不支持

最後

使用 DefinePlugin + TerserWebpackPlugin 配置,打包後發現 vConsole 沒了。能夠向老闆申請加雞腿了······

小貼士:ProvidePluginexternals 的區別,前者自動 import,後者是無需 npm install 便可直接 import

參考連接

  1. webpack選擇性編譯DefinePlugin(打包自動剔除測試數據)
  2. webpack的打包和性能優化
  3. webpack更新至4.26
相關文章
相關標籤/搜索