「知識拾遺」Tree-Shaking與構建工具選擇

  • 2019 年 12 月 21 日
  • 筆記

Tree-Shaking

Tree-Shaking,它代表的大意就是刪除沒用到的代碼。這樣的功能對於構建大型應用時是非常好的,因為日常開發經常需要引用各種庫。但大多時候僅僅使用了這些庫的某些部分,並非需要全部,此時Tree-Shaking如果能幫助我們刪除掉沒有使用的代碼,將會大大縮減打包後的代碼量。

Tree-Shaking的原理,通過靜態分析,找出未被引用、未被執行、無法到達的代碼進行消除,也就是DCE(dead code elimination)。要做到這一點,就必須保證模塊依賴關係是確定的,和運行時的狀態無關,而現在前端環境下,能做到這樣的,就是ES6 modules 。

ES6 Module特點

  • 只能作為模塊頂層的語句出現
  • import 的模塊名只能是字符串常量
  • import binding 是 immutable的

用打包工具輸出esm

再看現有的打包工具,webpack似乎佔領了"江湖"。於是自然想到,首先webpack作為打包工具,但是在定義模塊輸出的時候,webpack卻不支持ESM。webpack目前支持的格式如下:

out.libraryTarget屬性取值分別為:

  1. var – 默認值
  2. assign
  3. this
  4. window
  5. global
  6. commonjs
  7. commonjs2
  8. amd
  9. umd
  10. jsonp

這就很雞肋了,不支持輸出esm類型,所以寫類庫的時候,要導出esm的話,無法用webpack編譯。webpack插件系統龐大,確實有支持模塊級的Tree-Shacking的插件,如webpack-deep-scope-analysis-plugin。但是粒度更細化的,一個模塊裏面的某個方法,本來如果沒有被引用的話也可以去掉的,就不行了….這個時候,就要上rollup了。

rollup明顯的2大特性:

  1. 它支持導出ES模塊的包。
  2. 它支持程序流分析,能更加正確的判斷項目本身的代碼是否有副作用。

結論

rollup 採用 es6 原生的模塊機制進行模塊的打包構建,rollup 更着眼於未來,對 commonjs 模塊機制不提供內置的支持,是一款更輕量的打包工具。rollup 比較適合打包 js 的 sdk 或者封裝的框架等,例如,vue 的 esm 版本就是 rollup 打包的。而 webpack 比較適合打包一些應用,例如 SPA 或者同構項目等等。

相關熱門推薦

「知識拾遺」你應該知道的 https

「知識拾遺」 http2/http3總結