如何写好.babelrc?Babel的presets和plugins配置解析
什么是Babel
The compiler for writing next generation JavaScript.
官網是這么說的,翻譯一下就是下一代JavaScript 語法的編譯器。
作為前端開發,由于瀏覽器的版本和兼容性問題,很多JavaScript的新的方法都不能使用,等到可以大膽使用的時候,可能已經過去了好幾年。Babel就因此而生,它可以讓你放心使用大部分的JavaScript的新的標準的方法,然后編譯成兼容絕大多數的主流瀏覽器的代碼。
在升級到了Babel6.x版本之后,所有的插件都是可插拔的。這也意味著你安裝了Babel之后,是不能工作的,需要配置對應的.babelrc文件才能發揮完整的作用。下面就對Babel的presets和plugins配置做一個簡單解析。
預設(presets)
使用的時候需要安裝對應的插件,對應babel-preset-xxx,例如下面的配置,需要npm install babel-preset-es2015。
{
"presets": ["es2015"]
}
env
{
"presets": ["env", options]
}
最近新增的一個選項,有以下options選擇。
targets: { [string]: number },默認{}
需要支持的環境,可選例如:chrome, edge, firefox, safari, ie, ios, node,甚至可以制定版本,如node: 6.5。也使用node: current代表使用當前的版本。
browsers: Array<string>| string,默認[]
瀏覽器列表,使用的是browserslist,可選例如:last 2 versions, > 5%。
loose: boolean,默認false
是否使用寬松模式,如果設置為true,plugins里的插件如果允許,都會采用寬松模式。
debug: boolean,默認false
編譯是否會去掉console.log。
whitelist: Array<string>,默認[]
設置一直引入的plugins列表。
es2015/es2016/es2017/latest
{
"presets": ["es2015"]
}
es2015
使用es2015的,也就是我們常說的es6的相關方法,簡單翻譯如下,更多細節可以參看文檔。
check-es2015-constants // 檢驗const常量是否被重新賦值
transform-es2015-arrow-functions // 編譯箭頭函數
transform-es2015-block-scoped-functions // 函數聲明在作用域內
transform-es2015-block-scoping // 編譯const和let
transform-es2015-classes // 編譯class
transform-es2015-computed-properties // 編譯計算對象屬性
transform-es2015-destructuring // 編譯解構賦值
transform-es2015-duplicate-keys // 編譯對象中重復的key,其實是轉換成計算對象屬性
transform-es2015-for-of // 編譯for...of
transform-es2015-function-name // 將function.name語義應用于所有的function
transform-es2015-literals // 編譯整數(8進制/16進制)和unicode
transform-es2015-modules-commonjs // 將modules編譯成commonjs
transform-es2015-object-super // 編譯super
transform-es2015-parameters // 編譯參數,包括默認參數,不定參數和解構參數
transform-es2015-shorthand-properties // 編譯屬性縮寫
transform-es2015-spread // 編譯展開運算符
transform-es2015-sticky-regex // 正則添加sticky屬性
transform-es2015-template-literals // 編譯模版字符串
transform-es2015-typeof-symbol // 編譯Symbol類型
transform-es2015-unicode-regex // 正則添加unicode模式
transform-regenerator // 編譯generator函數
總結:常用的都覆蓋了,并不需要太關心內容,如果使用某些還不支持的語法導致報錯,可以回頭查一下支持的列表。
es2016
使用es2016的相關插件,也就是es7,更多細節可以參看文檔。
transform-exponentiation-operator // 編譯冪運算符
es2017
使用es2017的相關插件,也就是es8?,更多細節可以參看文檔。
syntax-trailing-function-commas // function最后一個參數允許使用逗號
transform-async-to-generator // 把async函數轉化成generator函數
latest
latest是一個特殊的presets,包括了es2015,es2016,es2017的插件(目前為止,以后有es2018也會包括進去)。
react
react是一個比較特別的官方推薦的presets,大概是因為比較火吧。加入了flow,jsx等語法,具體可以看文檔。
stage-x(stage-0/1/2/3/4)
stage-x和上面的es2015等有些類似,但是它是按照JavaScript的提案階段區分的,一共有5個階段。而數字越小,階段越靠后,存在依賴關系。也就是說stage-0是包括stage-1的,以此類推。
stage-4
已完成的提案,與年度發布的release有關,包含2015年到明年正式發布的內容。例如,現在是2016年,stage-4應該是包括es2015,es2016,es2017。經過測試,babel-preset-stage-4這個npm包是不存在的,如果你單純的需要stage-4的相關方法,需要引入es2015~es2017的presets。
stage-3
除了stage-4的內容,還包括以下插件,更多細節請看文檔。
transform-object-rest-spread // 編譯對象的解構賦值和不定參數
transform-async-generator-functions // 將async generator function和for await編譯為es2015的generator。
stage-2
除了stage-3的內容,還包括以下插件,更多細節請看文檔。
transform-class-properties // 編譯靜態屬性(es2015)和屬性初始化語法聲明的屬性(es2016)。
stage-1
除了stage-2的內容,還包括以下插件,更多細節請看文檔。
transform-class-constructor-call // 編譯class中的constructor,在Babel7中會被移除
transform-export-extensions // 編譯額外的exprt語法,如export * as ns from "mod";細節可以看這個
stage-0
除了stage-1的內容,還包括以下插件,更多細節請看文檔。
transform-do-expressions // 編譯do表達式
transform-function-bind // 編譯bind運算符,也就是::
插件(plugins)
其實看了上面的應該也明白了,presets,也就是一堆plugins的預設,起到方便的作用。如果你不采用presets,完全可以單獨引入某個功能,比如以下的設置就會引入編譯箭頭函數的功能。
{
"plugins": ["transform-es2015-arrow-functions"]
}
那么,還有一些方法是presets中不提供的,這時候就需要單獨引入了,介紹幾個常見的插件。
transform-runtime
{
"plugins": ["transform-runtime", options]
}
主要有以下options選擇。
helpers: boolean,默認true
boolean, 默認為true。
是否切換將內聯(inline)的 Babel helper(classCallCheck,extends等)替換為對moduleName的調用(形式為var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
欲了解更多,請查閱Helper aliasing。
polyfill: boolean,默認true
是否切換新的內置插件(Promise,Set,Map等)為使用非全局污染的 polyfill。
欲了解更多,請查閱core-jsaliasing。
regenerator: boolean,默認true
是否切換 generator 函數為不污染全局作用域的 regenerator 運行時。
欲了解更多,請查閱Regenerator aliasing。
moduleName: string,默認babel-runtime
使用對應module處理。
string,默認為"babel-runtime"。
當引入 helper 時,設置要使用的模塊的名稱/路徑。
示例:
{
"moduleName": "flavortown/runtime"
}
import extends from 'flavortown/runtime/helpers/extends';
這里的options一般不用自己設置,用默認的即可。這個插件最大的作用主要有幾下幾點:
解決編譯中產生的重復的工具函數,減小代碼體積
非實例方法的poly-fill,如Object.assign,但是實例方法不支持,如"foobar".includes("foo"),這時候需要單獨引入babel-polyfill
更多細節參見文檔。
為什么要使用Runtime transform
Babel 使用了非常小的 helpers 來實現諸如_extend等常用功能。默認情況下,它將被添加到每個通過 require 引用它的文件中。這種重復(操作)有時是不必要的,特別是當你的應用程序被拆分為多個文件時。
這時則需要使用transform-runtime:所有的 helper 都會引用模塊babel-runtime,以避免編譯輸出的重復問題。這個運行時會被編譯到你的構建版本當中。
這個轉譯器的另外一個目的就是為你的代碼創建一個沙盒環境。如果你使用了babel-polyfill,它提供了諸如Promise,Set以及Map之類的內置插件,這些將污染全局作用域。雖然這對于應用程序或命令行工具來說可能是好事,但如果你的代碼打算發布為供其他人使用的庫,或你無法完全控制代碼運行的環境,則會成為問題。
轉譯器將這些內置插件起了別名core-js,這樣你就可以無縫的使用它們,并且無需使用 polyfill。
https://babeljs.cn/docs/plugins/transform-runtime/
transform-remove-console
{
"plugins": ["transform-remove-console"]
}
使用這個插件,編譯后的代碼都會移除console.*,媽媽再也不用擔心線上代碼有多余的console.log了。當然很多時候,我們如果使用webpack,會在webpack中配置。
這也告訴我們,Babel不僅僅是編譯代碼的工具,還能對代碼進行壓縮,也許有一天,你不再需要代碼壓縮的插件了,因為你有了Babel!
自定義預設或插件
Babel支持自定義的預設(presets)或插件(plugins)。如果你的插件在npm上,可以直接采用這種方式"plugins": ["babel-plugin-myPlugin"],當然,你也可以縮寫,它和"plugins": ["myPlugin"]是等價的。此外,你還可以采用本地的相對路徑引入插件,比如"plugins": ["./node_modules/asdf/plugin"]。
presets同理。
plugins/presets排序
也許你會問,或者你沒注意到,我幫你問了,plugins和presets編譯,也許會有相同的功能,或者有聯系的功能,按照怎么的順序進行編譯?答案是會按照一定的順序。
具體而言,plugins優先于presets進行編譯。
plugins按照數組的index增序(從數組第一個到最后一個)進行編譯。
presets按照數組的index倒序(從數組最后一個到第一個)進行編譯。因為作者認為大部分會把presets寫成["es2015", "stage-0"]。具體細節可以看這個。
總結
因為自己對.babelrc文件的設置有點疑問,花了大半天擼了下官方的文檔。很多內容是英文的,可能翻譯并不準確,希望大家多多指教。
{
"presets": [
"es2015",
"stage-0"
],
"plugins": ["transform-runtime"]
}
json
當然,如果你的項目需要react或者flow這些語法的編譯,請在presets里加入對應的值即可。如果你需要非實例方法"foobar".includes("foo")之類的方法,按需引入babel-polyfill。
本文鏈接:https://excaliburhan.com/post/babel-preset-and-plugins.html
總結
以上是生活随笔為你收集整理的如何写好.babelrc?Babel的presets和plugins配置解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设置Loding延迟加载页面
- 下一篇: [时间序列分析]--平稳性,白噪声的检验