babel分析

如今都用 ES6 新語法以及 ES7 新特性來寫應用了,可是瀏覽器和相關的環境還不能友好的支持,須要用到 Babel 轉碼器來轉換成 ES5 的代碼node

相信你們都看到過以下的名詞:react

  • babel-preset-*
  • babel-plugin-*
  • babel-cli
  • babel-node
  • babel-core
  • babel-runtime
  • babel-plugin-transform-runtime
  • babel-polyfill

1、什麼是Bablewebpack

例如:web

// 轉碼前
input.map(item => item + 1);
 
// 轉碼後
input.map(function (item) {
return item + 1;
});
2、Babel 配置文件

使用 Babel 第一步就是在項目根目錄建立其配置文件 .babelrc,Babel 會自動查找並讀取內容。
該文件是用來設置 Babel 轉碼器的轉碼規則和可調用插件,基本格式以下:算法

1
2
3
4
{
"presets": [],
"plugins": []
}


注意:如下全部 Babel 工具和模塊的使用,都必須先寫好 .babelrcnpm

presets 字段


官方提供的功用轉碼規則有:json

  • env
  • es2015
  • es2016
  • es2017
  • latest (不推薦, 請使用 env)
  • react
  • flow

# 根據環境自動決定合適插件的規則,
# 轉譯最新的基礎語法
$ npm i --save-dev babel-preset-env
 
# 最新轉碼規則
# 官方不推薦使用
$ npm i --save-dev babel-preset-latest
 
# 也至關於最新轉碼規則
$ npm i --save-dev babel-preset-es2015
$ npm i --save-dev babel-preset-es2016
$ npm i --save-dev babel-preset-es2017
 
# 針對不一樣階段語法的轉碼規則(共有4個階段,選裝一個)
$ npm i --save-dev babel-preset-stage-0
$ npm i --save-dev babel-preset-stage-1
$ npm i --save-dev babel-preset-stage-2
$ npm i --save-dev babel-preset-stage-3
# 轉譯最新的 api 等,爲低版本環境提供墊片,其會自動按需引入
$ npm i -D babel-plugin-transform-runtime
{
"presets": [
"env",
"react"
],
"plugins": ["transform-runtime"]
}

babel-preset-stage-*:

每一項新特性,要最終歸入ECMAScript規範中,TC39擬定了一個處理過程,稱爲 TC39 Process。其中共包含5個階段,Stage 0 ~ Stage 4。api

Stage 0: strawman
稻草人階段。
一種推動 ECMAScript 發展的自由形式,任何 TC39 成員,或者註冊爲 TC39 貢獻者的會員,均可以提交。數組

Stage 1: proposal
提案階段。
該階段產生一個正式的提案。
(1)肯定一個帶頭人來負責該提案,帶頭人或者聯合帶頭人必須是 TC39 的成員。
(2)描述清楚要解決的問題,解決方案中必須包含例子,API 以及關於相關的語義和算法。
(3)潛在問題也應該指出來,例如與其餘特性的關係,實現它所面臨的挑戰。
(4)polyfill 和 demo 也是必要的。瀏覽器

Stage 2: draft
草案階段。
草案是規範的第一個版本,與最終標準中包含的特性不會有太大差異。草案以後,原則上只接受增量修改。
(1)草案中包含新增特性語法和語義的,儘量的完善的形式說明,容許包含一些待辦事項或者佔位符。
(2)必須包含2個實驗性的具體實現,其中一個能夠是用轉譯器實現的,例如Babel。

Stage 3: candidate
候選階段。
此階段得到具體實現和用戶的反饋。此後,只有在實現和使用過程當中出現了重大問題纔會修改。
(1)規範文檔必須是完整的,評審人和 ECMAScript 的編輯要在規範上簽字。
(2)至少要有兩個符合規範的具體實現。

Stage 4: finished
完成階段。
已經準備就緒,該特性會出如今年度發佈的規範之中。
(1)經過 Test 262 的驗收測試。
(2)有 2 個經過測試的實現,以獲取使用過程當中的重要實踐經驗。
(3)ECMAScript 的編輯必須規範上的簽字。

babel-preset-es2015/2016/2017

  • babel-preset-es2015
    只會將 ES2016 編譯爲 ES5
  • babel-preset-es2016
    只編譯 ES2016 的內容(到 ES2015)
  • babel-preset-es2017
    只編譯 ES2017 的內容(到 ES2016)

babel-preset-env

babel-preset-env 在沒有任何配置選項的狀況下,babel-preset-env 與 babel-preset-latest(或者babel-preset-es2015,babel-preset-es2016和babel-preset-es2017一塊兒)的行爲徹底相同(但不包含 Stage-X 的)。

babel-plugin-* 插件及與 babel-preset-* 預設插件的關係

preset的預設插件的功能會包含plugin的一些功能,可是同時plugin的有些功能preset不支持,例如:使用 babel-plugin-transform-remove-console。使用這個插件,編譯後的代碼都會移除 console.*,媽媽不再用擔憂線上代碼有多餘的 console.log 了。

presets / plugins 排序

plugins 和 presets編譯,也許會有相同的功能,或者有聯繫的功能,按照怎麼的順序進行編譯?答案是會按照必定的順序。

  • 具體而言,plugins 優先於 presets進行編譯。
  • plugins 按照數組的 index 增序(從數組第一個到最後一個)進行編譯。
  • presets 按照數組的 index 倒序(從數組最後一個到第一個)進行編譯。由於做者認爲大部分會把 presets 寫成 [「es2015」, 「stage-0」]。具體細節能夠看官方文檔。

babel-core 與 babel-register 的關係

這個就更簡單了。

仍是 babel-core 包下 register.js 文件的內容:

1
2
3
/* eslint max-len: 0 */
// TODO: eventually deprecate this console.trace("use the `babel-register` package instead of `babel-core/register`");
module.exports = require("babel-register");

 全局babel-polyfill(使用babel-preset-env插件和useBuiltIns屬性)

  • 使用方法
    • packge.json引入依賴babel-preset-env
    • .babelrc中使用配置preset-env
    • 指定useBuiltins選項爲true
    • 指定瀏覽器環境或node環境, 配置須要兼容的瀏覽器列表
    • webpack入口文件中使用import/require引入polyfill, 如import 'babel-polyfill'
    • 以上配置完成以後, babel會根據指定的瀏覽器兼容列表自動引入全部所需的polyfill, 無論你代碼中有沒有使用
  • .babelrc示例
{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["ie >=9"]
      },
      "useBuiltIns": true,
      "debug": true
    }]
  ]
}
  • 優勢
    • 按需(按照指定的瀏覽器環境所需)引入polyfill, 必定程度上減小了沒必要要polyfill的引入

    • 配置簡單, 無需對webpack作額外的配置


就這麼短短几行,代表了 babel-core 依賴於 babel-register 來實現一些核心的 API 函數。

因此這麼使用場景就很清楚了,須要實時轉譯 ES6 文件,就用 babel-register,簡單單一。

須要使用更高級的功能,也就是須要在實時轉譯時對轉譯過程和結果要來把控的話,就用 babel-core,利用其 API 來實現。

最後別忘了,使用這兩個 npm 包的時候,不能忘了安裝和引入咱們前幾節所說的 babel-preset-* 和 babel-plugin-* 插件呀!還有 .babelrc 配置文件是一切轉譯工做進行的前提呀!

相關文章
相關標籤/搜索