【第1065期】再見,babel-preset-2015

前端早讀課李昕2017-09-23 06:23:43

前言

醒醒,該更新了。今日早讀文章由阿里南京研發中@李昕授權分享。

正文從這開始~

我猜很多同學和我一樣每次使用 Babel 的時候,必選的 preset 就是 ES2015。

然而就在最近,如果你再次安裝 babel-preset-es2015 時

npm install --save-dev babel-preset-es2015

你會發現有如下的 Deprecated警告(文字很歡樂):

[email protected]: We're super 😸 excited that you're trying to use ES2015 syntax, but instead of making more yearly presets 😭 , Babel now has a better preset that we recommend you use instead: npm install babel-preset-env --save-dev. preset-env without options will compile ES2015+ down to ES5 just like using all the presets together and thus is more future proof. It also allows you to target specific browsers so that Babel can do less work and you can ship native ES2015+ to user 😎 ! We are also in the process of releasing v7, so please give http://babeljs.io/blog/2017/09/12/planning-for-7.0 a read and help test it out in beta! Thanks so much for using Babel 🙏, please give us a follow on Twitter @babeljs for news on Babel, join http://slack.babeljs.io for discussion/development and help support the project at opencollective.com/babel

是的,在2017年第三季度我們終於要和 ES2015 preset 説再見了。

那麼你可能會問我們是要遷移到 ES2017 了嗎?事實上並非如此,babel-preset-es2017 只是增加了一些特性而已,且仍然需要安裝 ES2015。好了,不賣關子了,答案就是——

你好,babel-preset-env

Babel 的官網上在9月宣佈 ES2015 / ES2016/ ES2017 等等 ES20xx 時代的 presets 通通被廢棄(deprecated),取而代之的是 babel-preset-env,並且承諾它將成為“未來不會過時的(future-proof)”解決方案。

在過去,Babel 將 babel-preset-es2015 放在 babel/babel 的主倉庫中進行維護,而 babel-preset-env 則獨立為一級項目,這從某種程度上也顯示出 Babel 官方對這款 preset 的重視程度和更長遠的規劃。

如何遷移

為了節省你的閲讀時間,我先給出一個如何升級的簡單版:

首先卸載原來的 preset,然後安裝 babel-preset-env:

npm uninstall --save-dev babel-preset-es2015
npm install --save-dev babel-preset-[email protected]

接下來將你的 .babelrc 文件中“es2015”修改“env”:

{
 "presets": [ "env" ],
 ...
}

好了,恭喜你,就這麼簡單,你已經可以與 ES2015+ 保持更新了!

更進一步

在 babel-preset-env 的官方説明中提到這是一款可以“自動”決定加載哪些插件和 polyfill 的 preset,既然是叫“env”,那麼一定是可以由開發者決定編譯目標處於什麼樣的運行環境。

targets 選項

通過 targets 指定需要兼容的瀏覽器類型和版本(採用 ai/browserslist 查詢語法 ):

{
 "presets": [
   ["env", {
     "targets": {
       "browsers": ["last 2 versions", "safari >= 7"]
     }
   }]
 ]
}

換句話説,你可以通過指定更高的瀏覽器版本來減少插件和 polyfill 的代碼量,並且直接使用原生 ES6 的新特性,特別適合 Electron 及移動端 App 或者那些已指定了瀏覽器的內網應用程序。例如,將瀏覽器設為 Chrome 較高的版本,Promise、Map、Set 等內建類均不會被 polyfill,而同時 class 等新語法也不會被 Babel 轉譯,轉而使用 V8 自帶的 ES6 Class。

如果你是用來開發 Node.js 應用,也同樣可以指定 Node 的版本:

{
 "presets": [
   ["env", {
     "targets": {
       "node": "6.10"
     }
   }]
 ]
}

為了方便,你也可以直接寫成 "node": "current",將自動採用你當前用來運行 Babel 的 Node.js 版本。

同時也可以在 targets 中指定 browsers 選項。

目前 targets 中支持了幾乎所有主流運行時環境,其中就包括了 IE、Chrome、Firefox、Opera、Edge、Safari、iOS Safari、Android、Node 和 Electron 等。

modules 選項

該選項與過去一致,用來指定模塊化方式,支持 AMD、UMD、SystemJS、CommonJS 等。當然在 Webpack 2/3 的時代,推薦將 modules 設置為 false,即交由 Webpack 來處理模塊化,通過其 TreeShaking 特性將有效減少打包出來的 JS 文件大小:

{
 "presets": [
   ["env", {
     modules: false,
     ...
   }]
 ]
}

從 Webpack 2 開始,已自動啟用對 Native Import 的支持,因此無需對 Webpack 進行額外設置,詳情請參考我的另一個答案Henry Li:ECMAScript 6 的模塊相比 CommonJS 的require (...)有什麼優點?

useBuiltIns 選項與 Polyfill

請注意:以下為 2.0-beta 的功能

這是一個關於 Polyfill 的選項,個人認為這是此次遷移後帶來的最大便利,當然首先你仍然需要額外安裝 babel-polyfill(是的,你不再需要額外的 transform)

npm install babel-polyfill --save

當 useBuiltIns 設置為 usage 時,Babel 會在你使用到 ES2015+ 新特性時,自動添加 babel-polyfill 的引用,並且是 partial 級別的引用。

請注意: usage 的行為類似 babel-transform-runtime,不會造成全局污染,因此也會不會對類似 Array.prototype.includes() 進行 polyfill。

例如:

const promise = new Promise();
const map = new Map();

會被轉譯為:

import "babel-polyfill/core-js/modules/es6.map";
import "babel-polyfill/core-js/modules/es6.promise";

var promise = new Promise();
var map = new Map();

很多人習慣於在 vendor 中一次性引入 babel-polyfill,在過去這將導致整個 babel-polyfill 包被打包到 vendor 中,在方便開發的同時失去了靈活性,而現在你可以將 useBuiltIns 設置為 entry,Babel 會自動進行優化:

例如:

vendor.js :

import 'babel-polyfill';

index.js:

const promise = new Promise();
const map = new Map();

最終 vendor.js 會被轉譯為:

import "babel-polyfill/core-js/modules/es6.map";
import "babel-polyfill/core-js/modules/es6.promise";

怎麼樣?是不是超級“智能”!

再見,babel-preset-es2015

現在,我們可以放心的説,是時候和 babel-preset-es2015 告別了。

babel-preset-env 目前正在不斷積極更新中,更多的 babel-preset-env 選項請參見 babel/babel-preset-env。

關於本文

作者:@李昕

原文:https://zhuanlan.zhihu.com/p/29506685

閲讀原文

TAGS:可以選項指定需要額外