jsliang 求職系列 - 33 - Webpack - Tree Shaking

一 目錄

不折騰的前端,和鹹魚有什麼區別css

目錄
一 目錄
二 前言
三 什麼是 dead-code
四 什麼是反作用?
五 如何作到 Tree Shaking
六 總結
七 其餘問題
7.1 提問 1:爲何能夠實現 Tree Shaking?
7.2 提問 2:下面哪一種狀況會 Tree Shaking?

二 前言

返回目錄

Tree ShakingWebpack 內置的一個優化,主要功能是移除 JavaScript 上下文中的未引用代碼(dead-code)。前端

由於 JavaScript 大多數文件是要經過網絡引用加載的,加載的文件越小,性能越好,因此 Tree Shaking 對於優化 JavaScript 頗有意義。webpack

你能夠將引用程序想象成一棵樹,而後裏面有枯死的樹葉和新鮮的樹葉,你搖動它,枯死的樹葉紛紛落下,你就看到一棵生機盎然的樹。git

三 什麼是 dead-code

返回目錄
  1. 代碼不會被執行
  2. 代碼執行結果不會被用到
  3. 代碼只會影響死變量

即 JavaScript 上下文中的未引用代碼(無用的,死的代碼)。github

舉個例子:web

project category
webpack-demo
 |- index.js
 |- main.js
main.js
export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}
index.js
import { cube } from './main.js';

const result = cube(5);
const p = document.querySelector('.p');
p.innerHTML = result;

在這裏,咱們並無引用方法 square,因此總體來講 square 是未引用代碼(dead-code),可是 Webpack 打包的時候會將 square 導出到 bundle 中。json

四 什麼是反作用?

返回目錄

反作用是指:在導入時會執行特殊行爲的代碼,而不是僅僅暴露一個 export 或者多個 export數組

舉個例子:polyfill 它影響全局做用域,而且一般不提供 export安全

五 如何作到 Tree Shaking

返回目錄

在 Webpack 中,作到 Tree Shaking 的方法就是將一些文件標明爲無反作用,這樣就能夠告知 Webpack 它能夠安全地刪除未用到的 export 導出。網絡

package.json
{
  "name": "jsliang-project",
  "sideEffects": false
}

像上面,經過在 package.json 中定義 sideEffects 屬性,就能夠將文件標記爲無反作用。

固然,若是有些文件你怕它有反作用,那就告知 Webpack 其中某些文件不須要標記:

package.json
{
  "name": "jsliang-project",
  "sideEffects": [
    "./src/math.js",
    "*.css*",
  ]
}

這裏能夠經過一個數組,數組支持 相關文件的相對路徑、絕對路徑和 glob 模式

這樣,咱們就找出了 未使用代碼dead-code)。

可是正如上面所說,只是告知,並無刪除。

若是咱們須要在 bundle 中刪除它們,就須要使用 -pproduction)這個 Webpack 編譯標記,來啓用 uglifyjs 壓縮插件。

注意: --optimize-minimize 標記也會在 Webpack 內部調用 UglifyJSPlugin

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  mode: "production"
};

六 總結

返回目錄

爲了達到 Tree Shaking 的做用,你須要:

  1. 使用 ES6 的模板語法 importexport
  2. 在項目 package.json 文件中,添加 sideEffects 入口。
  3. 引入一個可以刪除未引用代碼(dead-code)的壓縮工具(例如 UglifyJSPlugin

七 其餘問題

返回目錄

7.1 提問 1:爲何能夠實現 Tree Shaking?

返回目錄

ES6 模塊依賴關係是肯定的,和運行時的狀態無關,能夠進行可靠的靜態分析,這就是 Tree Shaking 的基礎。

所謂的 靜態分析,就是不執行代碼,從字面量上對代碼進行分析,ES6 以前的模塊化,好比咱們能夠動態 require 一個模塊,只有執行後才知道引用的什麼模塊,這個就不能經過靜態分析去作優化。

// demo.js
export const a = 'a';
export const b = 'b';

// test.js
import { a } from './demo.js';

// 以上代碼不運行,僅僅通過掃描分析,拋棄了 const b,代碼縮減了 size
// 這就是 Tree Shaking 的靜態分析基本原理:有引用就保留,沒有引用就拋棄

因此爲啥 CommonJS 不能 Tree Shaking 就是這個緣故。

7.2 提問 2:下面哪一種狀況會 Tree Shaking?

返回目錄
// 所有導入
import _ from 'lodash';

// 具名導入
import { debounce } from 'lodash';

// 直接導入具體模塊
import debounce from 'lodash/lib/debounce';

上面導入中:第一種的 所有導入 是不支持 Tree Shaking 的,其餘都支持。

爲何呢?由於當你將整個庫導入到單個 JavaScript 對象中時,就意味着你告訴 Webpack,你須要整個庫,這樣 Webpack 就不會搖它。


jsliang 的文檔庫由 梁峻榮 採用 知識共享 署名-非商業性使用-相同方式共享 4.0 國際 許可協議 進行許可。<br/>基於 https://github.com/LiangJunrong/document-library 上的做品創做。<br/>本許可協議受權以外的使用權限能夠從 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 處得到。
相關文章
相關標籤/搜索