Babel presets stage

在一些新框架的代碼中,常基於es6/7標準來書寫代碼。鑑於這些標準被沒有被瀏覽器普遍支持,咱們通常使用babel來將使用e6/7標準書寫的代碼降級編譯(或者說轉譯)爲瀏覽器可解析的es3/5代碼。css

以.babelrc文件配置babel爲例,presets預設編譯規則(預設的編譯插件集合)能夠設置stage-0 至 stage-3, stage-0包含了stage-1 至 stage-3,也就是說若是設置爲stage-0,stage-1 至 stage-3的編譯功能默認都有了。git

stage-0 至 stage-3表明了es標準支持的不一樣階段。0階段是最初級的階段,能夠理解爲僅僅纔開始討論標準, 換句話說就是基本沒有什麼瀏覽器支持es新標準。3表示成熟階段,意味着主流瀏覽器的新版本都支持大部分新標準,基礎的es新標準特性不須要降級編譯爲es5,瀏覽器便可原生支持。es6

 

stage-3包括如下插件:github

  transform-async-to-generator  支持async/awaitexpress

  transform-exponentiation-operator 支持冪運算符語法糖,用兩個**表示瀏覽器

 

stage-2包括stage-3的全部插件,額外還包括如下插件:babel

  syntax-trailing-function-commas 支持尾逗號函數,額...很雞肋antd

  transform-object-reset-spread 支持對象的解構賦值框架

 

stage-1包括stage-2全部插件,額外還包括如下插件:async

  transform-class-constructor-call 支持class的構造函數

  transform-class-properties 支持class的static成員(靜態屬性與靜態方法)

  transform-decorators  支持es7的裝飾者模式即@,這實際上是頗有用的特性,對於HOC來講這是一個不錯的語法糖

  transform-export-extensions 支持export方法

 

stage-0包括stage-1全部插件,額外還包括如下插件:

  transform-do-expressions 支持在jsx中書寫if/else

  transform-function-bind 支持::操做符來切換上下文,而且支持鏈式調用,做用相似於es5的bind

 

每一個插件所支持的特性在代碼上的具體體現可查看es6/7標準等詳細資料,或babel官方站點,

Babel默認只轉換新的JavaScript語法,但不會去轉換新的 API ,好比 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局對象,以及一些定在全局對象上定義的方法,例如:Object.assign等,這些都不會被轉換。 默認不轉碼的 API 很是多,詳情查看

也就是當咱們使用ES2015語法進行開發的時候,要去適配一些在ES2015定稿以前發行的瀏覽器,可能還須要使用到babel-polyfill,來保證上述提到的不被轉換的API等都可以有ES3/5的支持,從而確保咱們的項目在運行的時候不會因語法報錯而白屏。

 

在實際配置babel presets stage的時候,能夠根據業務要求、書寫愛好、文件大小以及要兼容的瀏覽器及其版原本酌情設置。

 

對於babel的核心和其餘插件,在實際項目開發中咱們經常使用的到的還有:

babel-core

它是babel實現最基礎代碼轉譯功能的核心,用於將咱們書寫的高級EcmaScript語法轉成AST語法抽象樹,分發給不一樣的插件進行語法分析,進而轉譯成低級的EcmaScript語法。

babel-runtime

包含降級轉譯所需的各類helper方法,以實現ES6的新特性,好比_extend、_defineProperty等。

babel-plugin-transform-runtime

這個插件的存在解決了polyfill引入而帶來的全局變量污染和語法降級helper重複的問題。試想若是咱們的項目不是全寫在一個JS文件裏,而是分散到不一樣的JS文件中去的,同一個高級EcamaScript語法可能在多個JS文件中被使用到,在降級轉譯高級語法的時候,會出現多個用於降級轉譯的helper,好比_extend、_defineProperty等,文件分散得越多,重複得可能性越大,最後轉譯出的靜態資源也就越大,這是很可怕的。這個插件的存在就是爲了解決這個問題,他提供了從 babel-runtime 獲取helper並插入到每一個須要編譯的JS文件內的功能。當每一個JS文件被轉譯時,其所需的helper都從 babel-runtime 這個統一的文件中require,而不是本身申明一個,這樣就避免了重複。而且它提供了一個沙盒環境用來限制一些新API的命名空間,防止全局變量出現污染,這對你在一個庫或者一個工具裏使用babel來講特別重要,你確定不但願你的庫或者工具分發給他人使用時,你的庫中的變量直接污染了全局變量空間吧。固然若是隻是咱們在本身的項目應用中使用,這種污染是能夠接受的。

babel-plugin-import

這是一個由antd發佈的插件,支持模塊的按需加載。好比咱們使用React和Antd做爲MVVM的庫和UI組件庫。對於Antd提供的UI組件咱們可能並不是全部的組件都有用到,由於一次性引入整個Antd(包括js和css)對咱們來講不是必要的,而咱們又不肯意import一個組件很長的文件路徑和對應的樣式路徑,對於咱們來講直接 import {Button} from 'antd'; 纔是最方便的。該插件即提供了這個功能,咱們只須要這樣寫就行,babel會幫咱們自動引入其關聯的樣式文件,而非整個Antd庫。

 

還有其餘的插件也有很大概率使用到,這取決於你的開發和測試需求,這裏就再也不過多講解,在babel官網中會有相應介紹,有興趣的同窗能夠自行查看。 

另外的,在.babelrc文件中,咱們通常須要配置plugins和presets,對於plugins和presets能夠這麼理解:

plugins的每一個內容項爲單獨的一個插件,執行順序從上到下。

而presets裏的每一個內容項表示爲實現某個功能的某些插件的集合,可能一個presets的配置項包含有多個插件,執行順位爲從下到上。

總的執行順序爲先執行plugins,再執行presets的內容。

相關文章
相關標籤/搜索