babel

babel官網 babel

介紹

Babel 是一個通用的多用途 JavaScript 編譯器。通過 Babel 你可以使用(并創建)下一代的 JavaScript,以及下一代的 JavaScript 工具。

作為一種語言,JavaScript 在不斷發展,新的標準/提案和新的特性層出不窮。 在得到廣泛普及之前,Babel 能夠讓你提前(甚至數年)使用它們。

Babel 把用最新標準編寫的 JavaScript 代碼向下編譯成可以在今天隨處可用的版本。 這一過程叫做“源碼到源碼”編譯, 也被稱為轉換編譯(transpiling,是一個自造合成詞,即轉換+編譯。以下也簡稱為轉譯)。

例如,Babel 能夠將新的 ES2015 箭頭函數語法:

const square = n => n * n;

轉譯為:

const square = function square(n) {
  return n * n;
};

不過 Babel 的用途并不止于此,它支持語法擴展,能支持像 React 所用的 JSX 語法,同時還支持用于靜態類型檢查的流式語法(Flow Syntax)。

更重要的是,Babel 的一切都是簡單的插件,誰都可以創建自己的插件,利用 Babel 的全部威力去做任何事情。

再進一步,Babel 自身被分解成了數個核心模塊,任何人都可以利用它們來創建下一代的 JavaScript 工具。

已經有很多人都這樣做了,圍繞著 Babel 涌現出了非常大規模和多樣化的生態系統。 在這本手冊中,我將介紹如何使用 Babel 的內建工具以及一些來自于社區的非常有用的東西。


安裝 Babel

由于 JavaScript 社區沒有統一的構建工具、框架、平臺等等,因此 Babel 正式集成了對所有主流工具的支持。 從 Gulp 到 Browserify,從 Ember 到 Meteor,不管你的環境設置如何,Babel 都有正式的集成支持。

本手冊的目的主要是介紹 Babel 內建方式的安裝,不過你可以訪問交互式的安裝頁面來查看其它的整合方式。

注意:
本手冊將涉及到一些命令行工具如 nodenpm。在繼續閱讀之前請確保你已經熟悉這些工具了。

babel-cli

Babel 的 CLI 是一種在命令行下使用 Babel 編譯文件的簡單方法。

讓我們先全局安裝它來學習基礎知識。

$ npm install --global babel-cli

我們可以這樣來編譯我們的第一個文件:

$ babel my-file.js

這將把編譯后的結果直接輸出至終端。使用 --out-file 或著 -o 可以將結果寫入到指定的文件。

$ babel example.js --out-file compiled.js
# 或
$ babel example.js -o compiled.js

如果我們想要把一個目錄整個編譯成一個新的目錄,可以使用 --out-dir 或者 -d

$ babel src --out-dir lib
# 或
$ babel src -d lib

在項目內運行 Babel CLI

盡管你可以把 Babel CLI 全局安裝在你的機器上,但是按項目逐個安裝在本地會更好。

有兩個主要的原因。

  1. 在同一臺機器上的不同項目或許會依賴不同版本的 Babel 并允許你有選擇的更新。
  2. 這意味著你對工作環境沒有隱式依賴,這讓你的項目有很好的可移植性并且易于安裝。

要在(項目)本地安裝 Babel CLI 可以運行:

$ npm install --save-dev babel-cli

注意:
因為全局運行 Babel 通常不是什么好習慣所以如果你想要卸載全局安裝的 Babel 的話,可以運行:

$ npm uninstall --global babel-cli

安裝完成后,你的 package.json 應該如下所示:

{
  "name": "my-project",
  "version": "1.0.0",
  "devDependencies": {
    "babel-cli": "^6.0.0"
  }
}

現在,我們不直接從命令行運行 Babel 了,取而代之我們將把運行命令寫在 npm scripts 里,這樣可以使用 Babel 的本地版本。

只需將 "scripts" 字段添加到你的 package.json 文件內并且把 babel 命令寫成 build 字段。

  {
    "name": "my-project",
    "version": "1.0.0",
+   "scripts": {
+     "build": "babel src -d lib"
+   },
    "devDependencies": {
      "babel-cli": "^6.0.0"
    }
  }

現在可以在終端里運行:

npm run build

這將以與之前同樣的方式運行 Babel,但這一次我們使用的是本地副本。

babel-register

下一個常用的運行 Babel 的方法是通過 babel-register。這種方法只需要引入文件就可以運行 Babel,或許能更好地融入你的項目設置。

但請注意這種方法并不適合正式產品環境使用。 直接部署用此方式編譯的代碼不是好的做法。 在部署之前預先編譯會更好。 不過用在構建腳本或是其他本地運行的腳本中是非常合適的。

讓我們先在項目中創建 index.js 文件。

console.log("Hello world!");

如果我們用 node index.js 來運行它是不會使用 Babel 來編譯的。所以我們需要設置 babel-register。.

首先安裝 babel-register。.

$ npm install --save-dev babel-register

接著,在項目中創建 register.js 文件并添加如下代碼:

require("babel-register");
require("./index.js");

這樣做可以把 Babel 注冊到 Node 的模塊系統中并開始編譯其中 require 的所有文件。

現在我們可以使用 register.js 來代替 node index.js 來運行了。

$ node register.js

注意:
你不能在你要編譯的文件內同時注冊 Babel,因為 node 會在 Babel 編譯它之前就將它執行了。

require("babel-register");
// 未編譯的:
console.log("Hello world!");

babel-node

如果你要用 node CLI 來運行代碼,那么整合 Babel 最簡單的方式就是使用 babel-node CLI,它是 node CLI 的替代品。

但請注意這種方法并不適合正式產品環境使用。 直接部署用此方式編譯的代碼不是好的做法。 在部署之前預先編譯會更好。 不過用在構建腳本或是其他本地運行的腳本中是非常合適的。

首先確保 babel-cli 已經安裝了。

$ npm install --save-dev babel-cli

注意:
如果您想知道我們為什么要在本地安裝,請閱讀 上面在項目內運行Babel CLI的部分。

然后用 babel-node 來替代 node 運行所有的代碼 。.

如果用 npm scripts 的話只需要這樣做:

  {
    "scripts": {
-     "script-name": "node script.js"
+     "script-name": "babel-node script.js"
    }
  }

要不然的話你需要寫全 babel-node 的路徑。

- node script.js
+ ./node_modules/.bin/babel-node script.js

提示:
你可以使用 npm-run

babel-core

如果你需要以編程的方式來使用 Babel,可以使用 babel-core 這個包。

首先安裝 babel-core。.

$ npm install babel-core

var babel = require("babel-core");

字符串形式的 JavaScript 代碼可以直接使用 babel.transform 來編譯。.

babel.transform("code();", options);
// => { code, map, ast }

如果是文件的話,可以使用異步 api:

babel.transformFile("filename.js", options, function(err, result) {
  result; // => { code, map, ast }
});

或者是同步 api:

babel.transformFileSync("filename.js", options);
// => { code, map, ast }

要是已經有一個 Babel AST(抽象語法樹)了就可以直接從 AST 進行轉換。

babel.transformFromAst(ast, code, options);
// => { code, map, ast }

對于上述所有方法,options 指的都是 http://babeljs.io/docs/usage/options/


配置 Babel

你或許已經注意到了,目前為止通過運行 Babel 自己我們并沒能“翻譯”代碼,而僅僅是把代碼從一處拷貝到了另一處。

這是因為我們還沒告訴 Babel 要做什么。

由于 Babel 是一個可以用各種花樣去使用的通用編譯器,因此默認情況下它反而什么都不做。你必須明確地告訴 Babel 應該要做什么。

你可以通過安裝 插件(plugins)預設(presets,也就是一組插件) 來指示 Babel 去做什么事情。

.babelrc

在我們告訴 Babel 該做什么之前,我們需要創建一個配置文件。你需要做的就是在項目的根路徑下創建 .babelrc 文件。然后輸入以下內容作為開始:

{
  "presets": [],
  "plugins": []
}

這個文件就是用來讓 Babel 做你要它做的事情的配置文件。

::: warning 注意
盡管你也可以用其他方式給 Babel 傳遞選項,但 .babelrc 文件是約定也是最好的方式。
:::

babel-preset-es2015

我們先從讓 Babel 把 ES2015(最新版本的 JavaScript 標準,也叫做 ES6)編譯成 ES5(現今在大多數 JavaScript 環境下可用的版本)開始吧。

我們需要安裝 "es2015" Babel 預設:

$ npm install --save-dev babel-preset-es2015

我們修改 .babelrc 來包含這個預設。

  {
    "presets": [
+     "es2015"
    ],
    "plugins": []
  }

babel-preset-react

設置 React 一樣容易。只需要安裝這個預設:

$ npm install --save-dev babel-preset-react

然后在 .babelrc 文件里補充:

  {
    "presets": [
      "es2015",
+     "react"
    ],
    "plugins": []
  }

babel-preset-stage-x

JavaScript 還有一些提案,正在積極通過 TC39(ECMAScript 標準背后的技術委員會)的流程成為標準的一部分。

這個流程分為 5(0-4)個階段。 隨著提案得到越多的關注就越有可能被標準采納,于是他們就繼續通過各個階段,最終在階段 4 被標準正式采納。

以下是4 個不同階段的(打包的)預設:

  • babel-preset-stage-0
  • babel-preset-stage-1
  • babel-preset-stage-2
  • babel-preset-stage-3

注意:
stage-4 預設是不存在的因為它就是上面的 es2015 預設。

以上每種預設都依賴于緊隨的后期階段預設。例如,babel-preset-stage-1 依賴 babel-preset-stage-2,后者又依賴 babel-preset-stage-3

使用的時候只需要安裝你想要的階段就可以了:

$ npm install --save-dev babel-preset-stage-2

然后添加進你的 .babelrc 配置文件。

  {
    "presets": [
      "es2015",
      "react",
+     "stage-2"
    ],
    "plugins": []
  }


執行 Babel 生成的代碼

即便你已經用 Babel 編譯了你的代碼,但這還不算完。

babel-polyfill

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

Uncaught TypeError: Array.from is not a function

為了解決這個問題,我們使用一種叫做 Polyfill(代碼填充,也可譯作兼容性補丁) 的技術。 簡單地說,polyfill 即是在當前運行環境中用來復制(意指模擬性的復制,而不是拷貝)尚不存在的原生 api 的代碼。 能讓你提前使用還不可用的 APIs,Array.from 就是一個例子。

Babel 用了優秀的 core-js 用作 polyfill,并且還有定制化的 regenerator 來讓 generators(生成器)和 async functions(異步函數)正常工作。

要使用 Babel polyfill,首先用 npm 安裝它:

$ npm install --save babel-polyfill

然后只需要在文件頂部導入 polyfill 就可以了:

import "babel-polyfill";

babel-runtime

為了實現 ECMAScript 規范的細節,Babel 會使用“助手”方法來保持生成代碼的整潔。

由于這些助手方法可能會特別長并且會被添加到每一個文件的頂部,因此你可以把它們統一移動到一個單一的“運行時(runtime)”中去。

通過安裝 babel-plugin-transform-runtimebabel-runtime 來開始。

$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save babel-runtime

然后更新 .babelrc

  {
    "plugins": [
+     "transform-runtime",
      "transform-es2015-classes"
    ]
  }

現在,Babel 會把這樣的代碼:

class Foo {
  method() {}
}

編譯成:

import _classCallCheck from "babel-runtime/helpers/classCallCheck";
import _createClass from "babel-runtime/helpers/createClass";

let Foo = function () {
  function Foo() {
    _classCallCheck(this, Foo);
  }

  _createClass(Foo, [{
    key: "method",
    value: function method() {}
  }]);

  return Foo;
}();

這樣就不需要把 _classCallCheck_createClass 這兩個助手方法放進每一個需要的文件里去了。


配置 Babel(進階)

大多數人使用 Babel 的內建預設就足夠了,不過 Babel 提供了更多更細粒度的能力。

手動指定插件

Babel 預設就是一些預先配置好的插件的集合,如果你想要做一些不一樣的事情你會手動去設定插件,這和使用預設幾乎完全相同。

首先安裝插件:

$ npm install --save-dev babel-plugin-transform-es2015-classes

然后往 .babelrc 文件添加 plugins 字段。.

  {
+   "plugins": [
+     "transform-es2015-classes"
+   ]
  }

這能讓你對正在使用的轉換器進行更細致的控制。

完整的官方插件列表請見 Babel 插件頁面

同時也別忘了看看由社區構建的其他插件。 如果你想學習如何編寫自己的插件可以閱讀 Babel 插件手冊

插件選項

很多插件也有選項用于配置他們自身的行為。 例如,很多轉換器都有“寬松”模式,通過放棄一些標準中的行為來生成更簡化且性能更好的代碼。

要為插件添加選項,只需要做出以下更改:

  {
    "plugins": [
-     "transform-es2015-classes"
+     ["transform-es2015-classes", { "loose": true }]
    ]
  }

基于環境自定義 Babel

Babel 插件解決許多不同的問題。 其中大多數是開發工具,可以幫助你調試代碼或是與工具集成。 也有大量的插件用于在生產環境中優化你的代碼。

因此,想要基于環境來配置 Babel 是很常見的。你可以輕松的使用 .babelrc 文件來達成目的。

  {
    "presets": ["es2015"],
    "plugins": [],
+   "env": {
+     "development": {
+       "plugins": [...]
+     },
+     "production": {
+       "plugins": [...]
+     }
    }
  }

Babel 將根據當前環境來開啟 env 下的配置。

當前環境可以使用 process.env.BABEL_ENV 來獲得。 如果 BABEL_ENV 不可用,將會替換成 NODE_ENV,并且如果后者也沒有設置,那么缺省值是"development"

Unix

$ BABEL_ENV=production [COMMAND]
$ NODE_ENV=production [COMMAND]

Windows

$ SET BABEL_ENV=production
$ [COMMAND]

注意:
[COMMAND] 指的是任意一個用來運行 Babel 的命令(如:babelbabel-node,或是 node,如果你使用了 register 鉤子的話)。

提示
如果你想要讓命令能夠跨 unix 和 windows 平臺運行的話,可以使用 cross-env

制作你自己的預設(preset)

手動指定插件?插件選項?環境特定設置?所有這些配置都會在你的項目里產生大量的重復工作。

為此,我們鼓勵社區創建自己的預設。 這可能是一個針對特定 node 版本的預設,或是適用于你整個公司的預設。

創建預設非常容易。比方說你這樣一個 .babelrc 文件:

{
  "presets": [
    "es2015",
    "react"
  ],
  "plugins": [
    "transform-flow-strip-types"
  ]
}

你要做的就是依循命名約定 babel-preset-* 來創建一個新項目(請務必對這個命名約定保持責任心,也就是說不要濫用這個命名空間),然后創建兩個文件。

首先,創建一個 package.json,包括針對預設所必要的 dependencies

{
  "name": "babel-preset-my-awesome-preset",
  "version": "1.0.0",
  "author": "James Kyle <me@thejameskyle.com>",
  "dependencies": {
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-react": "^6.3.13",
    "babel-plugin-transform-flow-strip-types": "^6.3.15"
  }
}

然后創建 index.js 文件用于導出 .babelrc 的內容,使用對應的 require 調用來替換 plugins/presets 字符串。

module.exports = {
  presets: [
    require("babel-preset-es2015"),
    require("babel-preset-react")
  ],
  plugins: [
    require("babel-plugin-transform-flow-strip-types")
  ]
};

然后只需要發布到 npm 于是你就可以像其它預設一樣來使用你的預設了。


Babel 和其他工具

一旦你掌握的竅門,安裝 Babel 還是十分簡明的,不過和其他工具搭配在一起就會變得困難多了。 不過我們一直在與其他項目密切合作以確保這種體驗盡可能簡單。

靜態分析工具

新標準為語言帶來了許多新的語法,靜態分析工具正在將此利用起來。

語法檢查(Linting)

ESLint 是最流行的語法檢查工具之一,因此我們維護了一個官方的 babel-eslint 整合軟件包。

首先安裝 eslintbabel-eslint。.

$ npm install --save-dev eslint babel-eslint

然后創建或使用項目現有的 .eslintrc 文件并設置 parserbabel-eslint。.

  {
+   "parser": "babel-eslint",
    "rules": {
      ...
    }
  }

現在添加一個 lint 任務到 npm 的 package.json 腳本中:

  {
    "name": "my-module",
    "scripts": {
+     "lint": "eslint my-files.js"
    },
    "devDependencies": {
      "babel-eslint": "...",
      "eslint": "..."
    }
  }

接著只需要運行這個任務就一切就緒了。

$ npm run lint

詳細信息請咨詢 babel-eslint 或者 eslint 的文檔。

代碼風格

JSCS已經和ESLint合并,所以請查看ESLint的代碼風格。

JSCS 是一個極受歡迎的工具,在語法檢查的基礎上更進一步檢查代碼自身的風格。 Babel 和 JSCS 項目的核心維護者之一(@hzoo)維護著 JSCS 的官方集成。

更妙的是,JSCS 自己通過 --esnext 選項實現了這種集成,于是和 Babel 的集成就簡化成了直接在命令行運行:

$ jscs . --esnext

或者在 .jscsrc 文件里添加 esnext 選項。

  {
    "preset": "airbnb",
+   "esnext": true
  }

詳細信息請咨詢 babel-jscs 或是 jscs 的文檔。

文檔

使用 Babel,ES2015,還有 Flow 你可以對你的代碼進行大量的推斷。使用 documentation.js 可以非常簡便地生成詳細的 API 文檔。

Documentation.js 使用 Babel 來支持所有最新的語法,包括用于在你的代碼中聲明類型所用的 Flow 注解在內。

框架

所有主流的 JavaScript 框架都正在努力調整他們的 APIs 向這門語言的未來看齊。有鑒于此,配套工具方面已經做出了大量的工作。

除了使用 Babel 以外,框架更有條件去擴展 Babel 來幫助他們提升用戶體驗。

React

React 已經大幅改變了他們的 API 以適應 ES2015 的類語法(此處了解更新的 API)。 特別是 React 現在依賴 Babel 編譯它的 JSX 語法且棄用了它原有的自定義工具。 你可以按照上述說明安裝 babel-preset-react 包來開始。.

React 社區采用 Babel 并圍繞它來運行,現在社區已經創建了大量的轉換器(transforms)。.

最令人矚目的是 babel-plugin-react-transform 插件,它集成了大量 React 專用轉換器可以啟用諸如 熱模塊重載等其他調試工具。

文本編輯器和 IDEs(集成開發環境)

通過 Babel 引入 ES2015,JSX,和流式語法固然是大有裨益,可如果你的文本編輯不支持那可就糟糕透了。 因此,別忘了為你的文本編輯器或是 IDE 安裝 Babel 插件。


Babel 支持

Babel 的社區非常龐大并且增長速度很快,伴隨著我們成長的同時我們希望保證人們總能獲取他們需要的所有資源。 所以我們提供了數種途徑來提供支持。

謹記在所有的這些溝通渠道里我們都共同遵守一套行為準則。 破壞準則的行為會被處理。 所以請閱讀它并在與他人互動時注意自己的行為。

Babel 論壇

Discourse 免費為我們提供了一個托管版本的論壇。 如果你是個論壇控請不要錯過 discuss.babeljs.io

Babel 聊天

無人不愛 Slack。如果你正在尋求來自社區的即時支持,那就來 slack.babeljs.io 和我們聊天吧。

Babel 問題

Babel使用Github提供的問題跟蹤器。.

您可以在Github上看到所有的開放和封閉的問題.

如果你想要打開一個新的問題:

創建漂亮的 Babel 錯誤報告

Babel 的問題有時候很難遠程調試,所以我們希望能獲取盡可能詳細的信息來幫助我們解決問題。 花點時間去撰寫一份好的錯誤報告會讓你的問題更快得到解決。

首先,嘗試隔離問題。 并非設置過程的每一步都是導致問題的原因。 如果你的問題是一段輸入代碼,試著盡可能把與問題不相關的代碼都刪除掉。

作者:不得不愛XIN
鏈接:http://www.lxweimin.com/p/11d0712b5d55
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。

babel官網 babel

介紹

Babel 是一個通用的多用途 JavaScript 編譯器。通過 Babel 你可以使用(并創建)下一代的 JavaScript,以及下一代的 JavaScript 工具。

作為一種語言,JavaScript 在不斷發展,新的標準/提案和新的特性層出不窮。 在得到廣泛普及之前,Babel 能夠讓你提前(甚至數年)使用它們。

Babel 把用最新標準編寫的 JavaScript 代碼向下編譯成可以在今天隨處可用的版本。 這一過程叫做“源碼到源碼”編譯, 也被稱為轉換編譯(transpiling,是一個自造合成詞,即轉換+編譯。以下也簡稱為轉譯)。

例如,Babel 能夠將新的 ES2015 箭頭函數語法:

const square = n => n * n;

轉譯為:

const square = function square(n) {
  return n * n;
};

不過 Babel 的用途并不止于此,它支持語法擴展,能支持像 React 所用的 JSX 語法,同時還支持用于靜態類型檢查的流式語法(Flow Syntax)。

更重要的是,Babel 的一切都是簡單的插件,誰都可以創建自己的插件,利用 Babel 的全部威力去做任何事情。

再進一步,Babel 自身被分解成了數個核心模塊,任何人都可以利用它們來創建下一代的 JavaScript 工具。

已經有很多人都這樣做了,圍繞著 Babel 涌現出了非常大規模和多樣化的生態系統。 在這本手冊中,我將介紹如何使用 Babel 的內建工具以及一些來自于社區的非常有用的東西。


安裝 Babel

由于 JavaScript 社區沒有統一的構建工具、框架、平臺等等,因此 Babel 正式集成了對所有主流工具的支持。 從 Gulp 到 Browserify,從 Ember 到 Meteor,不管你的環境設置如何,Babel 都有正式的集成支持。

本手冊的目的主要是介紹 Babel 內建方式的安裝,不過你可以訪問交互式的安裝頁面來查看其它的整合方式。

注意:
本手冊將涉及到一些命令行工具如 nodenpm。在繼續閱讀之前請確保你已經熟悉這些工具了。

babel-cli

Babel 的 CLI 是一種在命令行下使用 Babel 編譯文件的簡單方法。

讓我們先全局安裝它來學習基礎知識。

$ npm install --global babel-cli

我們可以這樣來編譯我們的第一個文件:

$ babel my-file.js

這將把編譯后的結果直接輸出至終端。使用 --out-file 或著 -o 可以將結果寫入到指定的文件。

$ babel example.js --out-file compiled.js
# 或
$ babel example.js -o compiled.js

如果我們想要把一個目錄整個編譯成一個新的目錄,可以使用 --out-dir 或者 -d

$ babel src --out-dir lib
# 或
$ babel src -d lib

在項目內運行 Babel CLI

盡管你可以把 Babel CLI 全局安裝在你的機器上,但是按項目逐個安裝在本地會更好。

有兩個主要的原因。

  1. 在同一臺機器上的不同項目或許會依賴不同版本的 Babel 并允許你有選擇的更新。
  2. 這意味著你對工作環境沒有隱式依賴,這讓你的項目有很好的可移植性并且易于安裝。

要在(項目)本地安裝 Babel CLI 可以運行:

$ npm install --save-dev babel-cli

注意:
因為全局運行 Babel 通常不是什么好習慣所以如果你想要卸載全局安裝的 Babel 的話,可以運行:

$ npm uninstall --global babel-cli

安裝完成后,你的 package.json 應該如下所示:

{
  "name": "my-project",
  "version": "1.0.0",
  "devDependencies": {
    "babel-cli": "^6.0.0"
  }
}

現在,我們不直接從命令行運行 Babel 了,取而代之我們將把運行命令寫在 npm scripts 里,這樣可以使用 Babel 的本地版本。

只需將 "scripts" 字段添加到你的 package.json 文件內并且把 babel 命令寫成 build 字段。

  {
    "name": "my-project",
    "version": "1.0.0",
+   "scripts": {
+     "build": "babel src -d lib"
+   },
    "devDependencies": {
      "babel-cli": "^6.0.0"
    }
  }

現在可以在終端里運行:

npm run build

這將以與之前同樣的方式運行 Babel,但這一次我們使用的是本地副本。

babel-register

下一個常用的運行 Babel 的方法是通過 babel-register。這種方法只需要引入文件就可以運行 Babel,或許能更好地融入你的項目設置。

但請注意這種方法并不適合正式產品環境使用。 直接部署用此方式編譯的代碼不是好的做法。 在部署之前預先編譯會更好。 不過用在構建腳本或是其他本地運行的腳本中是非常合適的。

讓我們先在項目中創建 index.js 文件。

console.log("Hello world!");

如果我們用 node index.js 來運行它是不會使用 Babel 來編譯的。所以我們需要設置 babel-register。.

首先安裝 babel-register。.

$ npm install --save-dev babel-register

接著,在項目中創建 register.js 文件并添加如下代碼:

require("babel-register");
require("./index.js");

這樣做可以把 Babel 注冊到 Node 的模塊系統中并開始編譯其中 require 的所有文件。

現在我們可以使用 register.js 來代替 node index.js 來運行了。

$ node register.js

注意:
你不能在你要編譯的文件內同時注冊 Babel,因為 node 會在 Babel 編譯它之前就將它執行了。

require("babel-register");
// 未編譯的:
console.log("Hello world!");

babel-node

如果你要用 node CLI 來運行代碼,那么整合 Babel 最簡單的方式就是使用 babel-node CLI,它是 node CLI 的替代品。

但請注意這種方法并不適合正式產品環境使用。 直接部署用此方式編譯的代碼不是好的做法。 在部署之前預先編譯會更好。 不過用在構建腳本或是其他本地運行的腳本中是非常合適的。

首先確保 babel-cli 已經安裝了。

$ npm install --save-dev babel-cli

注意:
如果您想知道我們為什么要在本地安裝,請閱讀 上面在項目內運行Babel CLI的部分。

然后用 babel-node 來替代 node 運行所有的代碼 。.

如果用 npm scripts 的話只需要這樣做:

  {
    "scripts": {
-     "script-name": "node script.js"
+     "script-name": "babel-node script.js"
    }
  }

要不然的話你需要寫全 babel-node 的路徑。

- node script.js
+ ./node_modules/.bin/babel-node script.js

提示:
你可以使用 npm-run

babel-core

如果你需要以編程的方式來使用 Babel,可以使用 babel-core 這個包。

首先安裝 babel-core。.

$ npm install babel-core

var babel = require("babel-core");

字符串形式的 JavaScript 代碼可以直接使用 babel.transform 來編譯。.

babel.transform("code();", options);
// => { code, map, ast }

如果是文件的話,可以使用異步 api:

babel.transformFile("filename.js", options, function(err, result) {
  result; // => { code, map, ast }
});

或者是同步 api:

babel.transformFileSync("filename.js", options);
// => { code, map, ast }

要是已經有一個 Babel AST(抽象語法樹)了就可以直接從 AST 進行轉換。

babel.transformFromAst(ast, code, options);
// => { code, map, ast }

對于上述所有方法,options 指的都是 http://babeljs.io/docs/usage/options/


配置 Babel

你或許已經注意到了,目前為止通過運行 Babel 自己我們并沒能“翻譯”代碼,而僅僅是把代碼從一處拷貝到了另一處。

這是因為我們還沒告訴 Babel 要做什么。

由于 Babel 是一個可以用各種花樣去使用的通用編譯器,因此默認情況下它反而什么都不做。你必須明確地告訴 Babel 應該要做什么。

你可以通過安裝 插件(plugins)預設(presets,也就是一組插件) 來指示 Babel 去做什么事情。

.babelrc

在我們告訴 Babel 該做什么之前,我們需要創建一個配置文件。你需要做的就是在項目的根路徑下創建 .babelrc 文件。然后輸入以下內容作為開始:

{
  "presets": [],
  "plugins": []
}

這個文件就是用來讓 Babel 做你要它做的事情的配置文件。

::: warning 注意
盡管你也可以用其他方式給 Babel 傳遞選項,但 .babelrc 文件是約定也是最好的方式。
:::

babel-preset-es2015

我們先從讓 Babel 把 ES2015(最新版本的 JavaScript 標準,也叫做 ES6)編譯成 ES5(現今在大多數 JavaScript 環境下可用的版本)開始吧。

我們需要安裝 "es2015" Babel 預設:

$ npm install --save-dev babel-preset-es2015

我們修改 .babelrc 來包含這個預設。

  {
    "presets": [
+     "es2015"
    ],
    "plugins": []
  }

babel-preset-react

設置 React 一樣容易。只需要安裝這個預設:

$ npm install --save-dev babel-preset-react

然后在 .babelrc 文件里補充:

  {
    "presets": [
      "es2015",
+     "react"
    ],
    "plugins": []
  }

babel-preset-stage-x

JavaScript 還有一些提案,正在積極通過 TC39(ECMAScript 標準背后的技術委員會)的流程成為標準的一部分。

這個流程分為 5(0-4)個階段。 隨著提案得到越多的關注就越有可能被標準采納,于是他們就繼續通過各個階段,最終在階段 4 被標準正式采納。

以下是4 個不同階段的(打包的)預設:

  • babel-preset-stage-0
  • babel-preset-stage-1
  • babel-preset-stage-2
  • babel-preset-stage-3

注意:
stage-4 預設是不存在的因為它就是上面的 es2015 預設。

以上每種預設都依賴于緊隨的后期階段預設。例如,babel-preset-stage-1 依賴 babel-preset-stage-2,后者又依賴 babel-preset-stage-3

使用的時候只需要安裝你想要的階段就可以了:

$ npm install --save-dev babel-preset-stage-2

然后添加進你的 .babelrc 配置文件。

  {
    "presets": [
      "es2015",
      "react",
+     "stage-2"
    ],
    "plugins": []
  }


執行 Babel 生成的代碼

即便你已經用 Babel 編譯了你的代碼,但這還不算完。

babel-polyfill

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

Uncaught TypeError: Array.from is not a function

為了解決這個問題,我們使用一種叫做 Polyfill(代碼填充,也可譯作兼容性補丁) 的技術。 簡單地說,polyfill 即是在當前運行環境中用來復制(意指模擬性的復制,而不是拷貝)尚不存在的原生 api 的代碼。 能讓你提前使用還不可用的 APIs,Array.from 就是一個例子。

Babel 用了優秀的 core-js 用作 polyfill,并且還有定制化的 regenerator 來讓 generators(生成器)和 async functions(異步函數)正常工作。

要使用 Babel polyfill,首先用 npm 安裝它:

$ npm install --save babel-polyfill

然后只需要在文件頂部導入 polyfill 就可以了:

import "babel-polyfill";

babel-runtime

為了實現 ECMAScript 規范的細節,Babel 會使用“助手”方法來保持生成代碼的整潔。

由于這些助手方法可能會特別長并且會被添加到每一個文件的頂部,因此你可以把它們統一移動到一個單一的“運行時(runtime)”中去。

通過安裝 babel-plugin-transform-runtimebabel-runtime 來開始。

$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save babel-runtime

然后更新 .babelrc

  {
    "plugins": [
+     "transform-runtime",
      "transform-es2015-classes"
    ]
  }

現在,Babel 會把這樣的代碼:

class Foo {
  method() {}
}

編譯成:

import _classCallCheck from "babel-runtime/helpers/classCallCheck";
import _createClass from "babel-runtime/helpers/createClass";

let Foo = function () {
  function Foo() {
    _classCallCheck(this, Foo);
  }

  _createClass(Foo, [{
    key: "method",
    value: function method() {}
  }]);

  return Foo;
}();

這樣就不需要把 _classCallCheck_createClass 這兩個助手方法放進每一個需要的文件里去了。


配置 Babel(進階)

大多數人使用 Babel 的內建預設就足夠了,不過 Babel 提供了更多更細粒度的能力。

手動指定插件

Babel 預設就是一些預先配置好的插件的集合,如果你想要做一些不一樣的事情你會手動去設定插件,這和使用預設幾乎完全相同。

首先安裝插件:

$ npm install --save-dev babel-plugin-transform-es2015-classes

然后往 .babelrc 文件添加 plugins 字段。.

  {
+   "plugins": [
+     "transform-es2015-classes"
+   ]
  }

這能讓你對正在使用的轉換器進行更細致的控制。

完整的官方插件列表請見 Babel 插件頁面

同時也別忘了看看由社區構建的其他插件。 如果你想學習如何編寫自己的插件可以閱讀 Babel 插件手冊

插件選項

很多插件也有選項用于配置他們自身的行為。 例如,很多轉換器都有“寬松”模式,通過放棄一些標準中的行為來生成更簡化且性能更好的代碼。

要為插件添加選項,只需要做出以下更改:

  {
    "plugins": [
-     "transform-es2015-classes"
+     ["transform-es2015-classes", { "loose": true }]
    ]
  }

基于環境自定義 Babel

Babel 插件解決許多不同的問題。 其中大多數是開發工具,可以幫助你調試代碼或是與工具集成。 也有大量的插件用于在生產環境中優化你的代碼。

因此,想要基于環境來配置 Babel 是很常見的。你可以輕松的使用 .babelrc 文件來達成目的。

  {
    "presets": ["es2015"],
    "plugins": [],
+   "env": {
+     "development": {
+       "plugins": [...]
+     },
+     "production": {
+       "plugins": [...]
+     }
    }
  }

Babel 將根據當前環境來開啟 env 下的配置。

當前環境可以使用 process.env.BABEL_ENV 來獲得。 如果 BABEL_ENV 不可用,將會替換成 NODE_ENV,并且如果后者也沒有設置,那么缺省值是"development"

Unix

$ BABEL_ENV=production [COMMAND]
$ NODE_ENV=production [COMMAND]

Windows

$ SET BABEL_ENV=production
$ [COMMAND]

注意:
[COMMAND] 指的是任意一個用來運行 Babel 的命令(如:babelbabel-node,或是 node,如果你使用了 register 鉤子的話)。

提示
如果你想要讓命令能夠跨 unix 和 windows 平臺運行的話,可以使用 cross-env

制作你自己的預設(preset)

手動指定插件?插件選項?環境特定設置?所有這些配置都會在你的項目里產生大量的重復工作。

為此,我們鼓勵社區創建自己的預設。 這可能是一個針對特定 node 版本的預設,或是適用于你整個公司的預設。

創建預設非常容易。比方說你這樣一個 .babelrc 文件:

{
  "presets": [
    "es2015",
    "react"
  ],
  "plugins": [
    "transform-flow-strip-types"
  ]
}

你要做的就是依循命名約定 babel-preset-* 來創建一個新項目(請務必對這個命名約定保持責任心,也就是說不要濫用這個命名空間),然后創建兩個文件。

首先,創建一個 package.json,包括針對預設所必要的 dependencies

{
  "name": "babel-preset-my-awesome-preset",
  "version": "1.0.0",
  "author": "James Kyle <me@thejameskyle.com>",
  "dependencies": {
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-react": "^6.3.13",
    "babel-plugin-transform-flow-strip-types": "^6.3.15"
  }
}

然后創建 index.js 文件用于導出 .babelrc 的內容,使用對應的 require 調用來替換 plugins/presets 字符串。

module.exports = {
  presets: [
    require("babel-preset-es2015"),
    require("babel-preset-react")
  ],
  plugins: [
    require("babel-plugin-transform-flow-strip-types")
  ]
};

然后只需要發布到 npm 于是你就可以像其它預設一樣來使用你的預設了。


Babel 和其他工具

一旦你掌握的竅門,安裝 Babel 還是十分簡明的,不過和其他工具搭配在一起就會變得困難多了。 不過我們一直在與其他項目密切合作以確保這種體驗盡可能簡單。

靜態分析工具

新標準為語言帶來了許多新的語法,靜態分析工具正在將此利用起來。

語法檢查(Linting)

ESLint 是最流行的語法檢查工具之一,因此我們維護了一個官方的 babel-eslint 整合軟件包。

首先安裝 eslintbabel-eslint。.

$ npm install --save-dev eslint babel-eslint

然后創建或使用項目現有的 .eslintrc 文件并設置 parserbabel-eslint。.

  {
+   "parser": "babel-eslint",
    "rules": {
      ...
    }
  }

現在添加一個 lint 任務到 npm 的 package.json 腳本中:

  {
    "name": "my-module",
    "scripts": {
+     "lint": "eslint my-files.js"
    },
    "devDependencies": {
      "babel-eslint": "...",
      "eslint": "..."
    }
  }

接著只需要運行這個任務就一切就緒了。

$ npm run lint

詳細信息請咨詢 babel-eslint 或者 eslint 的文檔。

代碼風格

JSCS已經和ESLint合并,所以請查看ESLint的代碼風格。

JSCS 是一個極受歡迎的工具,在語法檢查的基礎上更進一步檢查代碼自身的風格。 Babel 和 JSCS 項目的核心維護者之一(@hzoo)維護著 JSCS 的官方集成。

更妙的是,JSCS 自己通過 --esnext 選項實現了這種集成,于是和 Babel 的集成就簡化成了直接在命令行運行:

$ jscs . --esnext

或者在 .jscsrc 文件里添加 esnext 選項。

  {
    "preset": "airbnb",
+   "esnext": true
  }

詳細信息請咨詢 babel-jscs 或是 jscs 的文檔。

文檔

使用 Babel,ES2015,還有 Flow 你可以對你的代碼進行大量的推斷。使用 documentation.js 可以非常簡便地生成詳細的 API 文檔。

Documentation.js 使用 Babel 來支持所有最新的語法,包括用于在你的代碼中聲明類型所用的 Flow 注解在內。

框架

所有主流的 JavaScript 框架都正在努力調整他們的 APIs 向這門語言的未來看齊。有鑒于此,配套工具方面已經做出了大量的工作。

除了使用 Babel 以外,框架更有條件去擴展 Babel 來幫助他們提升用戶體驗。

React

React 已經大幅改變了他們的 API 以適應 ES2015 的類語法(此處了解更新的 API)。 特別是 React 現在依賴 Babel 編譯它的 JSX 語法且棄用了它原有的自定義工具。 你可以按照上述說明安裝 babel-preset-react 包來開始。.

React 社區采用 Babel 并圍繞它來運行,現在社區已經創建了大量的轉換器(transforms)。.

最令人矚目的是 babel-plugin-react-transform 插件,它集成了大量 React 專用轉換器可以啟用諸如 熱模塊重載等其他調試工具。

文本編輯器和 IDEs(集成開發環境)

通過 Babel 引入 ES2015,JSX,和流式語法固然是大有裨益,可如果你的文本編輯不支持那可就糟糕透了。 因此,別忘了為你的文本編輯器或是 IDE 安裝 Babel 插件。


Babel 支持

Babel 的社區非常龐大并且增長速度很快,伴隨著我們成長的同時我們希望保證人們總能獲取他們需要的所有資源。 所以我們提供了數種途徑來提供支持。

謹記在所有的這些溝通渠道里我們都共同遵守一套行為準則。 破壞準則的行為會被處理。 所以請閱讀它并在與他人互動時注意自己的行為。

Babel 論壇

Discourse 免費為我們提供了一個托管版本的論壇。 如果你是個論壇控請不要錯過 discuss.babeljs.io

Babel 聊天

無人不愛 Slack。如果你正在尋求來自社區的即時支持,那就來 slack.babeljs.io 和我們聊天吧。

Babel 問題

Babel使用Github提供的問題跟蹤器。.

您可以在Github上看到所有的開放和封閉的問題.

如果你想要打開一個新的問題:

創建漂亮的 Babel 錯誤報告

Babel 的問題有時候很難遠程調試,所以我們希望能獲取盡可能詳細的信息來幫助我們解決問題。 花點時間去撰寫一份好的錯誤報告會讓你的問題更快得到解決。

首先,嘗試隔離問題。 并非設置過程的每一步都是導致問題的原因。 如果你的問題是一段輸入代碼,試著盡可能把與問題不相關的代碼都刪除掉。

作者:不得不愛

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,794評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內容

  • babel官網 babel 介紹 Babel 是一個通用的多用途 JavaScript 編譯器。通過 Babel ...
    不得不愛XIN閱讀 1,153評論 0 9
  • Babel 入門指南 ?:warning: 注意:Babel 可以與很多構建工具(如 Browserify、Gru...
    靜默虛空閱讀 2,556評論 0 4
  • 由于新版本的ECMASscript的強大特性,使我們寫js代碼更加得心應手,例如:calss,let,for......
    緣自世界閱讀 2,654評論 0 2
  • 前言 半年前也寫過一篇babel的簡單使用文章,當時看了下babel的文檔,但是很多地方還不理解,所以文章里沒有怎...
    mercurygear閱讀 46,086評論 9 100
  • 一、事件驅動 在項目中使用 ES6 語法,并可以通過 Babel 將 ES6 代碼轉換為 ES5 的代碼,然后真正...
    神秘者007閱讀 1,034評論 0 0