Babel 是 JavaScript 編譯器,更確切地說是源碼到源碼的編譯器,一般也叫作「轉換編譯器(transpiler)」。node
若是你須要以編程的方式來使用 Babel,可使用 babel-core 這個包react
npm install babel-core var babel = require("babel-core");
字符串形式的 JavaScript 代碼能夠直接使用 babel.transform 來編譯webpack
babel.transform("code();....", options); // => { code, map, ast }
若是是文件的話,可使用異步 apiios
babel.transformFile("./myCode.js", options, function(err, result) { result; // => { code, map, ast } });
對於上述全部方法,options 指的都是http://babeljs.io/docs/usage/...web
在options中能夠設置presets和plugins,或者建立.babelrc文件,options默認開啓讀取babelrc文件的功能。如下是開啓自定義預設和插件的例子:chrome
const {transform,generate}=require('babel-core'); const myPlugin=require('./myPlugin'); const mypreset=require('./mypreset'); const code = `d = a + b + c`; var es5Code = transform(code, { plugins: [myPlugin], presets: [mypreset] }) console.log(es5Code.code);
在咱們告訴 Babel 該作什麼以前,咱們須要建立一個配置文件。你須要作的就是在項目的根路徑下建立 .babelrc 文件。而後輸入如下內容做爲開始:npm
{ "presets": [], "plugins": [] }
因爲babelrc的功能默認被開啓,可在options中設置{babelrc:false}來顯式關閉。編程
預設,包含一系列插件的集合。目前經常使用的presets包括es201x,stage-x,env,latest,react,flow。目前羅列的只是babel6的狀況。segmentfault
1. es2015api
check-es2015-constants
transform-es2015-arrow-functions
transform-es2015-block-scoped-functions
transform-es2015-block-scoping
transform-es2015-classes
transform-es2015-computed-properties
transform-es2015-destructuring
transform-es2015-duplicate-keys
transform-es2015-for-of
transform-es2015-function-name
transform-es2015-literals
transform-es2015-modules-commonjs
transform-es2015-object-super
transform-es2015-parameters
transform-es2015-shorthand-properties
transform-es2015-spread
transform-es2015-sticky-regex
transform-es2015-template-literals
transform-es2015-typeof-symbol
transform-es2015-unicode-regex
transform-regenerator
2. es2016
transform-exponentiation-operator
3. es2017
syntax-trailing-function-commas
transform-async-to-generator
es201x系列中,只羅列了當年ECMAScript公佈的新特性中的語法部分,至於新特性中的API則所有在polyfill中。
JavaScript 還有一些提案,正在積極經過 TC39(ECMAScript 標準背後的技術委員會)的流程成爲標準的一部分。
這個流程分爲 5(0-4)個階段。 隨着提案獲得越多的關注就越有可能被標準採納,因而他們就繼續經過各個階段,最終在階段 4 被標準正式採納。
如下是5 個不一樣階段的(打包的)預設:
以上每種預設都依賴於緊隨的後期階段預設。例如,babel-preset-stage-0 包含了 babel-preset-stage-1 babel-preset-stage-2 babel-preset-stage-3。
stage預設是一個一直變化的插件集合,根據當年發佈的標準內容,動態改變stage的插件內容,stage3中的候選插件極可能被完成,那就會在babel新release的版本中去除,而stage2中的草案就會進入到stage3中的候選名單中,像是一個傳接棒的過程,固然草案或者候選的名單隨時可能會被取消。
其中stage-0的do語法糖能夠很好的用在jsx中,咱們在開發recat的jsx條件判斷代碼時,能夠有如下幾種方式:
1.第一種三元表達式
{condition1?condition2?result1:result2:result3}
2.第二種自執行函數
{(()=>{ if(a){ return ...; }else{ return ...; } })()}
3.第三種do
{
do{ if(a){ 'result1' }else{ 'result2' } }
}
{ "presets": [ ["env", { "targets": { "browsers": ["last 2 versions", "safari >= 7"] } }] ] }
當env的配置只簡單配置爲{presets:['env']}時,與babel-preset-latest(官方已不推薦使用)等價,至關於同時集合了三個babel-preset-es201x預設。
env的執行過程是,首先讀取browsers配置中的條件,根據這些條件從browserslist模塊可得出該條件下的全部瀏覽器最低版本號列表,而env又爲babel的轉譯插件提供了瀏覽器的最低版本號列表,兩個瀏覽器版本號列表的查詢可得出一個babel轉譯插件的集合。
browserslist根據條件查出的瀏覽器及版本號:
1%, Last 2 versions => {ie:10,chrome:56...}
env提供的轉譯插件對應瀏覽器版本號列表:
{ "check-es2015-constants": { "chrome": "49", "edge": "14", "firefox": "51", "safari": "10", "node": "6", "ios": "10", "opera": "36", "electron": "1" }, "transform-es2015-arrow-functions": { "chrome": "47", "edge": "13", "firefox": "45", "safari": "10", "node": "6", "ios": "10", "opera": "34", "electron": "0.36" }....
最後得出結果
{ plugins:[babel插件1,babel插件2...] }
Babel 幾乎能夠編譯全部時新的 JavaScript 語法,但對於 APIs 來講卻並不是如此。
比方說,下列含有箭頭函數的須要編譯的代碼:
function addAll() { return Array.from(arguments).reduce((a, b) => a + b); }
最終會變成這樣:
function addAll() { return Array.from(arguments).reduce(function(a, b) { return a + b; }); }
然而,它依然沒法隨處可用由於不是全部的 JavaScript 環境都支持 Array.from。
babel墊片有三種:
babel-runtime和 babel-plugin-transform-runtime的區別是,至關一前者是手動擋然後者是自動擋,每當要轉譯一個api時都要手動加上require('babel-runtime'),而babel-plugin-transform-runtime會由工具自動添加,主要的功能是爲api提供沙箱的墊片方案,不會污染全局的api,所以適合用在第三方的開發產品中。
babel-polyfill則是經過改寫全局prototype的方式實現,比較適合單獨運行的項目。開啓babel-polyfill的方式,能夠直接在代碼中require,或者在webpack的entry中添加,也能夠在babel的env中設置useBuildins爲true來開啓。