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件事:
- 當使用generators/async功能時,自動新增babel-runtime/regenerator
- 自動新增babel-runtime/core-js並且對映ES6靜態方法和內建方法
- 移除內聯的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
注意:
- 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。所以按需載入是更好的方式。
實戰中遇到的問題:
- 使用webpack4的code split功能時,webpack未自動打包promise polyfill transform-runtime只能識別webpack處理前需要自動polyfill的靜態方法和內建物件。所以,使用webpack的code split時,promise的polyfill不會自動新增。一種解決方法時手動引入promise的polyfill或者在js程式碼中新增window.Promise =Promise。這樣webpack就能是識別到Promise,並自動新增polyfill