按需引入polyfill

**  參考文檔:你真的會用 Babel 嗎?node

在開發過程當中,若是咱們寫的代碼是es6語法的,其中有不少語法如:async、Array.isArray、Object.assign等等是低版本瀏覽器所不支持的。爲了保證咱們寫的es6語法可以在各個新舊客戶端上撒歡跑,咱們須要引入polyfill對這些新的語法進行全局注入。react

不引入的結果是:頁面報錯webpack


如何引入polyfill?

方法1、es6

全局引入polyfill:在webpack的入口文件中引入:import '@babel/polyfill' ;web

它會讓咱們程序的執行環境,模擬成完美支持 es6+ 的環境,畢竟不管是瀏覽器環境仍是 node 環境對 es6+ 的支持都不同。它是以重載全局變量 (E.g: Promise),還有原型和類上的靜態方法(E.g:Array.prototype.reduce/Array.form),從而達到對 es6+ 的支持。不一樣於 babel-runtime 的是,babel-polyfill 是一次性引入你的項目中的,就像是 React 包同樣,同項目代碼一塊兒編譯到生產環境。segmentfault

缺點:全局引入 @babel/polyfill 的這種方式可能會導入代碼中不須要的 polyfill,從而使打包體積更大數組

改進:使用useBuiltInsenv 會自動根據咱們的運行環境,去判斷須要什麼樣的 polyfill,並且,打包後的代碼體積也會大大減少,可是這一切要配置 useBuiltIns,並且須要你安裝 babel-polyfill,並 import。它會啓用一個插件,替換你的import 'babel-polyfill',不是整個引入了,而是根據你配置的環境和我的須要單獨的引入 polyfill。瀏覽器

用法:bash

{babel

"presets": [
    [
      "@babel/env",
      {
        "modules": "commonjs",  //設置ES6 模塊轉譯的模塊格式 默認是 commonjs
        "useBuiltIns": "usage", 
      }
    ]
  ],
}複製代碼

開啓 "useBuiltIns": "usage"後,打包後文件的大小明顯縮小了。從857 KiB =》610 KiB

須要注意的是useBuiltIns:falseuseBuiltIns:entry的打包效果是同樣的。而且使用了`useBuiltIns: 'usage'以後,就沒必要手動在入口文件中`import '@babel/polyfill'` ,不然會有以下warning:

When setting `useBuiltIns: 'usage'`, polyfills are automatically imported when needed. Please remove the `import '@babel/polyfill'` call or use `useBuiltIns: 'entry'` + `import '@babel/polyfill'`instead.

方法2、在babelrc文件中配置@babel/transform-runtime 

{

"presets": [
    [
      "@babel/env",
      {
        "modules": "commonjs",  //設置ES6 模塊轉譯的模塊格式 默認是 commonjs
      }
    ]
  ],
  "plugins": [
    "@babel/transform-react-jsx", //若是是須要支持 jsx 這個東西要單獨裝一下。
    "@babel/transform-runtime", 
  ]
}複製代碼

優勢:transform-runtime會根據檢測API是否須要重寫,而後按需寫入須要的API。這樣就能夠很大程度上減小打包文件的體積,並且 transform-runtime 不會污染原生的對象,方法,也不會對其餘 polyfill 產生影響。因此 transform-runtime 的方式更適合開發工具包,庫,一方面是體積夠小,另外一方面是用戶(開發者)不會由於引用了咱們的工具,包而污染了全局的原生方法,產生反作用,仍是應該留給用戶本身去選擇。

缺點:instance 上新添加的一些方法,babel-plugin-transform-runtime 是沒有作處理的,好比 數組的 includes, filter, fill 等。舉個例子,在代碼中寫了一個filter方法,在本身的瀏覽器運行完美。但測試小姐姐一測,發現她在瀏覽器上就沒法使用某個功能,調試發現是 filter 不支持,難受不😣

總結

  • 打包體積:全局引入 @babel/polyfill + "useBuiltIns": "usage"的方式,能夠根據環境判斷要引入哪些prolyfill,這個能夠有效減小打包後代碼的體積;babel-polyfill 是配置了執行環境的,經過環境看你須要哪些 polyfill,而 transform-runtime,是發現咱們代碼須要什麼 polyfill就重寫哪些polyfill。因此使用transform-runtime後打包體積是小於@babel/polyfill + "useBuiltIns": "usage"的。 
  • 全局污染:@babel/polyfill比較暴力,會重寫代碼中的原生對象、方法,而transform-runtime不會。 
  • polyfill的廣度:instance 上新添加的一些方法,babel-plugin-transform-runtime 是沒有作處理的,好比 數組的 includes, filter, fill 等
相關文章
相關標籤/搜索