文章概覽
本文主要內容包括:什麼是Babel Plugin、Babel Preset,二者的區別與聯繫、如何使用plugin/preset、如何建立自定義preset、使用注意事項。javascript
本文全部例子可在 筆者github 上 找到。java
Babel Plugin簡介
Babel是代碼轉換器,好比將ES6轉成ES5,或者將JSX轉成JS等。藉助Babel,開發者能夠提早用上新的JS特性,這對生產力的提高大有幫助。react
實現Babel代碼轉換功能的核心,就是Babel插件(plugin)。git
原始代碼 --> [Babel Plugin] --> 轉換後的代碼github
Babel Plugin例子
源代碼以下,這裏用到了兩個ES6才支持的新特性:箭頭函數、for...of。在只支持ES5的瀏覽器裏,這兩段代碼會報錯。npm
所以,能夠藉助插件將代碼轉成ES5。json
// index.js // 箭頭函數 [1,2,3].map(n => n + 1); // 模板字面量 let nick = '程序猿小卡'; let desc = `hello ${nick}`;
安裝依賴:瀏覽器
npm install --save-dev babel-cli npm install --save-dev babel-plugin-transform-es2015-arrow-functions npm install --save-dev babel-plugin-babel-plugin-transform-es2015-template-literals
執行轉換,經過--plugins
聲明依賴的插件,多個插件之間採用,
進行分隔。bash
`npm bin`/babel --plugins babel-plugin-transform-es2015-arrow-functions,babel-plugin-transform-es2015-template-literals index.js
轉換結果以下:babel
[1, 2, 3].map(function (n) { return n + 1; }); let nick = '程序猿小卡'; let desc = 'hello ' + nick;
轉換命令中,插件名稱能夠省去babel-plugin
前綴:
`npm bin`/babel --plugins transform-es2015-arrow-functions,transform-es2015-template-literals index.js
也能夠改爲配置文件 .babelrc,plugins
字段中聲明的插件會按照順序執行。
{ "plugins": [ "transform-es2015-arrow-functions", "transform-es2015-template-literals" ] }
再次執行轉換命令:
`npm bin`/babel
Babel Preset簡介
Babel插件通常儘量拆成小的力度,開發者能夠按需引進。好比對ES6轉ES5的功能,Babel官方拆成了20+個插件。
這樣的好處顯而易見,既提升了性能,也提升了擴展性。好比開發者想要體驗ES6的箭頭函數特性,那他只須要引入transform-es2015-arrow-functions
插件就能夠,而不是加載ES6全家桶。
但不少時候,逐個插件引入的效率比較低下。好比在項目開發中,開發者想要將全部ES6的代碼轉成ES5,插件逐個引入的方式使人抓狂,不單費力,並且容易出錯。
這個時候,能夠採用Babel Preset。
能夠簡單的把Babel Preset視爲Babel Plugin的集合。好比babel-preset-es2015
就包含了全部跟ES6轉換有關的插件。
下面經過例子說明。
Babel Preset例子
仍是原來的代碼,此次採用babel-preset-es2015
進行轉換。
首先,安裝依賴:
npm install --save-dev babel-cli npm install --save-dev babel-preset-es2015
執行轉換,經過--presets
聲明依賴的preset,多個preset之間用,
作分隔。
`npm bin`/babel --presets babel-preset-es2015 index.js `npm bin`/babel --presets es2015 index.js # 也能夠去掉 babel-preset 前綴
一樣能夠採用配置文件 .babelrc。
{ "presets": [ "es2015" ] }
轉換命令:
`npm bin`/babel
Plugin與Preset執行順序
能夠同時使用多個Plugin和Preset,此時,它們的執行順序很是重要。
- 先執行完全部Plugin,再執行Preset。
- 多個Plugin,按照聲明次序順序執行。
- 多個Preset,按照聲明次序逆序執行。
好比.babelrc
配置以下,那麼執行的順序爲:
- Plugin:transform-react-jsx、transform-async-to-generator
- Preset:es201六、es2015
{ "plugins": [ "transform-react-jsx", "transform-async-to-generator" ], "presets": [ "es2015", "es2016" ] }
下面經過簡單例子進行說明。
Plugin、Preset混用例子
例子:將 index.jsx 編譯成 index.js,而且採用 ES5規範。這裏包含兩個步驟:
- 將
jsx
語法轉成js
語法。 - 將 ES6規範 轉成 ES5規範。
源代碼以下:
// index.jsx var profile = <div> <img src="avatar.png" className="profile" /> <h3>{[user.firstName, user.lastName].join(' ')}</h3> </div>; var foo = () => "foo";
安裝依賴:
npm install --save-dev babel-cli npm install --save-dev babel-plugin-transform-react-jsx npm install --save-dev babel-preset-es2015
配置文件 .babelrc:
{ "plugins": [ "transform-react-jsx" ], "presets": [ "es2015" ] }
執行轉換:
`npm bin`/babel index.jsx
轉換結果以下:
"use strict"; var profile = React.createElement( "div", null, React.createElement("img", { src: "avatar.png", className: "profile" }), React.createElement( "h3", null, [user.firstName, user.lastName].join(' ') ) ); var foo = function foo() { return "foo"; };
讀者能夠試下下面命令,單獨採用bebel-preset-es2015
進行代碼轉換,結果會報語法錯誤。這從側面能夠印證Plugin的執行順序在Preset以前。
`npm bin`/babel --presets es2015 index.jsx
自定義Babel Preset
前面提到,Preset是Plugin的集合。藉助強大的社區,常見的轉換功能都已經有人實現的,不少時候,開發者只須要按需引用便可。
在實際開發中,咱們須要用到的Plugin/Preset相對比較固定,若是每次都要重複編寫,或者拷貝babel配置文件,既繁瑣,又容易出錯。這個時候,能夠考慮自定義Babel Preset。
之前面的 index.jsjsx 編譯爲例,咱們用到了 babel-preset-es201五、babel-plugin-transform-react-jsx,能夠建立自定義的 preset,把它們包含進去:()
// mypreset.js module.exports = { presets: [ require("babel-preset-es2015"), ], plugins: [ require("babel-plugin-transform-react-jsx"), ] };
而後,修改.babelrc。這裏由於是本地文件,全部用到了相對路徑,若是發佈到了npm上,就能夠直接用包名。
{ "presets": [ "./mypreset.js" ] }
轉碼過程略,讀者自行嘗試。
Plugin/Preset配置項
Babel Plugin、Babel Preset都支持配置項,配置項語法都是相同的,以下所示(插件相似)。
{ "presets": [ presetName01, // 沒有配置 [ presetName02, presetOptions02 ] // 有配置 ] }
具體例子以下:
{ "presets": [ ["es2015", { "loose": true, "modules": false }] ] }
不一樣Plugin/Preset的配置項做用可能不一樣,具體請查閱它們的官方文檔。