[轉] 最近折騰 @babel/preset-env 的一些小心得


近來廠里的項目越來越多,代碼共享必不可少。我現在采取的方案是:

  1. 把公共組件拿出來,開一個新倉庫
  2. 使用 webpack 進行打包編譯,libraryTarget: 'umd'
  3. 將打包編譯的代碼一起提交到倉庫
  4. 使用 npm i <owner>/<repo> -S 安裝依賴,因為我廠的倉庫均為私有,所以不能發布到 NPM

這套方案簡單好用,實操效果良好。接下來我希望優化打包結果,於是研究了打包配置項,下面是我的一點心得。

@babel/preset-env

首先,Babel 推薦使用 @babel/preset-env 套件來處理轉譯需求。顧名思義,preset 即“預制套件”,包含了各種可能用到的轉譯工具。之前的以年份為准的 preset 已經廢棄了,現在統一用這個總包。

同時,babel 已經放棄開發 stage-* 包,以后的轉譯組件都只會放進 preset-env 包里。

browserslist

@babel/preset-env 支持一些參數,用來處理哪些 feature 要轉譯,哪些不要。其中比較重要的是 targets,用來指定目標環境。targets 使用 browserslist 來篩選瀏環境,這樣我們就不需要指定所有瀏覽器版本,而可以使用類似 last 2 versions 這樣的描述。具體怎寫,可以看文檔,這里不再贅述。

如果你想知道自己配置的是否合適,可以在倉庫目錄下執行 npx browserslist,列出所有目標瀏覽器,比如:

zhailujiadeiMac:fe meathill$ npx browserslist
and_chr 73
and_ff 66
and_qq 1.2
and_uc 11.8
android 67
android 4.4.3-4.4.4
baidu 7.12
chrome 73
chrome 72
edge 18
edge 17
firefox 66
firefox 65
ios_saf 12.2
ios_saf 12.0-12.1
kaios 2.5
op_mini all
op_mob 46
op_mob 12.1
opera 58
opera 57
safari 12.1
safari 12
samsung 9.2
samsung 8.2
Bash

Babel 官方建議我們把 targets 寫到 .browserslistrc 或者 package.json 里,這樣其它工具也能更輕易的獲取到目標瀏覽器。另外,npx browserslist 無法從 .babelrc 等 babel 配置文件里讀取配置,所以執行的時候看到的會是默認結果。

useBuiltIns

接下來,我們可以配置 useBuiltIns,這個屬性決定是否引入 polyfill。它有三個可選值,默認是 false,即不引入,或者說,Babel 編譯結果不引入,把引入的位置、引入哪些 polyfill 交給用戶處理。因為我們的頁面中通常有大量的 JS,在每個文件里分別引用 polyfill 太浪費資源,所以可以在核心入口 JS 引用一次即可。

但是這樣我們必須手動 import '@babel/polyfill' 引入所有 polyfill,其實並不理想,因為大部分瀏覽器不需要這些。

所以推薦用 useBuiltIns: 'usage' 即“按需引用”。雖然文檔中標記為“experimental”,但我用起來也沒遇到什么問題。如果目標瀏覽器不支持需要的 feature,那么就引入 polyfill,不然的話就不引用。由於目前的打包工具越發智能,隨着 tree shaking 的完善,這樣可以最低限度引入 polyfill。

core-js

core-js 目前最新版本是 3.0.1,關於 v3 和 v2 的對比,大家可以看這篇博文:https://github.com/zloirock/core-js/blob/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md。這里簡單總結一下,core-js 2 封版於 1.5 年之前,所以里面只有對 1.5 年之前 feature 的 polyfill,最近 1.5 年新增的 feature 都不支持,也就存在因為新功能沒有 polyfill 於是在舊瀏覽器里失敗的風險。

所以我們應當升級到最新版,npm i core-js@3 -D 然后修改 babel 配置:

{ "presets": [ [ "@babel/preset-env", { "targets": "> 5%", "useBuiltIns": "usage", "corejs": 3 } ] ] }
JSON

注意,目前 Vue Cli 3 集成了 core-js 2,不支持升級到 v3,無法手動升級。需要等待 Vue Cli 4。

@babel/polyfill

@babel/polyfill 是對 core-js 的封裝,引用了 core-js 的內容和生成器(regenerator-runtime)。 v7.4 之后,這個倉庫就被廢棄了,希望用戶自己選擇使用哪個兼容庫。

換言之,以前:

import "@babel/polyfill";
JavaScript

需要被替換成

import "core-js/stable"; import "regenerator-runtime/runtime";
JavaScript

不過我不建議這么做。對於絕大部分情況,使用 @babel/preset-env + useBuiltIns: 'usage' 仍然是最好的選擇。


總結

這些知識並不復雜,基本上文檔里都有。不過一次性看大量英文文檔可能對很多同學來說都是負擔。我比較提倡這樣學習:

  1. 遇到需求就去看一遍,不求全部理解,能解決目前的問題即可
  2. 重復這個過程,爭取每次都比上一次理解更多
  3. 建立不同工具之間的邏輯體系,要求能夠內恰
  4. 繼續重復這個過程,知道確認自己理解了
  5. 通過看文檔鞏固


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM