關於babel-polyfill和babel-runtime

midsummer發表於2018-06-22

Babel 預設只轉換新的 JavaScript語法,而不轉換新的API。例如,Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全域性物件,以及一些定義在全域性物件上的方法都不會轉譯。如果想使用這些新的物件和方法,必須使用 polyfill。提供polyfill的有2個外掛:babel-runtime和babel-polyill。

關於babel-runtime

babel 對一些公共方法使用了非常小的輔助程式碼,比如 _extend。預設情況下會被新增到每一個需要它的檔案中可以引入 babel runtime 作為一個獨立模組,來避免重複引入。 需要

yarn add babel-plugin-transform-runtime --dev 
複製程式碼

來把它包含到你的專案中,也要使用

yarn add babel-runtime --dev 
複製程式碼

把 babel-runtime 安裝為一個依賴

翻譯自官網: runtime transformer plugin做3件事:

  1. 當使用generators/async功能時,自動新增babel-runtime/regenerator
  2. 自動新增babel-runtime/core-js並且對映ES6靜態方法和內建方法
  3. 移除內聯的babel幫助程式碼並使用babel-runtime/helpers模組來替代 簡單來說,基本上你可以使用內建函式如Promise,Set,Symbol等;也可以無縫地使用需要polyfill的所有Babel特性,而不會汙染全域性,對於庫來說很實用。 一定要把babel-runtime作為依賴引入!

babel-polyfill Babel 有一個 polyfill ,它包括 a custom regenerator runtime 和 core-js. babel-polyfill會完整的模擬ES2015+的環境,目標是用於應用中而不是庫或工具中。使用babel-node時,它會自動的載入。 這意味你能使用內建的函式如Promise或WeakMap,靜態方法如Array.from 或 Object.assign,例項方法如Array.prototype.includes,以及generator函式。為了實現這些方法,它被新增到全域性,也被新增到原生的原型上。

如果不想汙染全域性可以使用transform-runtime外掛,但這意味著你無法使用上述提到的例項方法。

babel-polyfill babel-plugin-transform-runtime transform-runtime 會自動應用 polyfill,即便沒有使用 babel-polyfill

注意:

  1. fetch方法不在polyfill中需要單獨載入包
yarn add whatwg-fetch
複製程式碼

關於babel-polyfill和babel-runtime具體用哪些方法是有區別的可以檢視core-js 2. 總結來說

// .babelrc
{
  "presets": ["env"],
  "plugins": [
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }]
  ]
}
複製程式碼

這種配置下,runtime不會新增任何polyfill。

// .babelrc
{
  "presets": ["env"],
  "plugins": ["transform-runtime"],
}

複製程式碼

只要把polyfill改成true即可,babel會自動識別程式碼裡用到了哪些物件方法,並自動polyfill這些方法。而這其實是預設開啟的,可以寫成如上的配置。(如要要支援一些例項方法等還是需要單獨引入對應的polyfill)

babel-polyfill壓縮後105kb,壓縮前249kb。所以按需載入是更好的方式。

實戰中遇到的問題:

  1. 使用webpack4的code split功能時,webpack未自動打包promise polyfill transform-runtime只能識別webpack處理前需要自動polyfill的靜態方法和內建物件。所以,使用webpack的code split時,promise的polyfill不會自動新增。一種解決方法時手動引入promise的polyfill或者在js程式碼中新增window.Promise =Promise。這樣webpack就能是識別到Promise,並自動新增polyfill

相關文章