首先,做爲入門的話,Babel的用戶手冊是個很不錯的選擇,裏面基本覆蓋了Babel使用的各方面。因此下面主要是我學習Babel的一些筆記,姑且看成是一篇入門吧。javascript
按照Babel官網的說法,Babel是一個Javascript編譯器。它能夠把用最新標準編寫的Javascript代碼編譯成如今的瀏覽器或者node環境下能運行的代碼,這個過程叫作「源碼到源碼」編譯,又稱轉譯(transpiling)。經過這個方式,咱們就能夠提早使用下一代的標準和特性進行編碼,而後在如今的環境下運行。html
一般咱們使用Babel的babel-cli
工具在命令行下進行文件的編譯。咱們能夠對babel-cli進行全局安裝,也能夠把它安裝到項目裏。這裏我選擇了把它安裝到項目裏。這樣作的好處是:java
不一樣的項目可能會使用不一樣版本的Babel,使用全局的話只能使用一致的版本node
方便項目的部署,使用全局安裝的話意味着對環境有個隱式的依賴。webpack
除了
babel-cli
,還有其餘使用Babel的方式,具體能夠看用戶手冊。git
下面咱們開始安裝babel-cli
。首先新建一個工做目錄,並建立package.json
文件:es6
$ npm init -y
安裝babel-cli
:github
$ npm install --save-dev babel-cli
安裝完咱們能夠這樣運行:web
$ ./node_modules/babel-cli/bin/babel.js -V 6.11.4 (babel-core 6.11.4)
可是這樣運行很不方便,咱們能夠經過npm scripts
來運行Babel。在package.json
文件裏,咱們增長scripts
字段,並添加一個腳本:npm
{ "scripts": { "build": "babel src -d lib" }, "devDependencies": { "babel-cli": "^6.11.4" } }
這裏增長了一條名字爲build
的腳本,命令的內容是把src
裏的文件經過Babel轉譯到lib
目錄裏。而後咱們能夠經過如下命令運行腳本:
$ npm run build
固然,如今運行這個命令會報錯,由於咱們並無src
文件夾。下面咱們正式進入正題。
首先咱們建立src
目錄,而後建立一個js文件index.js
:
[1,2,3].map(n => n + 1);
而後運行npm run build
命令,就會看到lib
文件夾裏多了一個轉譯後的文件index.js
。可是打開來看會發現這個轉譯後的文件跟源文件並無區別。由於Babel須要你經過插件(Plugin)
或者預設(presets)
告訴它作什麼。例如咱們能夠經過babel-preset-es2015
告訴Babel把ES2015的文件轉譯成ES5。這也是Babel最經常使用的一個用法之一。
要使用插件或者預設(至關於一組插件),咱們須要在Bable的配置文件裏面進行配置。有兩個方式進行配置。
第一個方式是經過.babelrc
文件:
{ "presets": [], "plugins": [] }
第二個方式是使用package.json
文件:
{ "name": "my-package", "version": "1.0.0", "babel": { "presets": [], "plugins": [] } }
上面說過,預設就是一組插件的集合,例如預設babel-preset-es2015
就是把一堆跟ES2015有關的插件組合起來提供編譯ES2015代碼爲ES5代碼的功能。下面咱們開始使用babel-preset-es2015
預設來把ES2015轉譯成ES5。
首先咱們安裝這個預設:
$ npm install --save-dev babel-preset-es2015
而後在配置文件裏添加這個預設:
{ "presets": [ "es2015" ], "plugins": [] }
最後咱們再次運行一次npm run build
命令,再次打開lib/index.js
文件,咱們會看到代碼已經被編譯成ES5的語法:
"use strict"; [1, 2, 3].map(function (n) { return n + 1; });
像上面那段轉譯後的代碼咱們能夠直接使用在當前的環境下,可是並非全部轉譯後的文件咱們都只能直接使用,由於雖然Babel能夠編譯目前幾乎全部的ES2015語法,可是一些新的API可能在當前的Javascript環境下沒法支持。例以下面的代碼(假設文件爲lib/index.js
):
function addAll() { return Array.from(arguments).reduce((a, b) => a + b); }
轉譯後會變成:
function addAll() { return Array.from(arguments).reduce(function(a, b) { return a + b; }); }
能夠看到語法上已經轉譯成ES5了,可是並非全部的Javascript環境都支持Array.from
,例如咱們在IE上運行以下頁面:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <script src="lib/index.js"></script> <script> console.log(addAll(1, 2, 3, 4, 5)); </script> </body> </html>
可能會報如下的錯誤:
對象不支持「from」屬性或方法
Babel的解決方法就是使用Polyfill技術(使用了core-js和regenerator),經過在當前的運行環境模擬不存在的API來達到使用新API的目的。
首先咱們安裝babel-polyfill
:
$ npm install --save babel-polyfill
注意這裏使用的是--save
而不是--save-dev
,由於咱們須要在代碼裏引入babel-polyfill
。咱們須要在文件頂部導入它:
import "babel-polyfill";
在添加這句代碼後,上面的代碼在轉譯後會變成下面這個樣子:
"use strict"; require("babel-polyfill"); function addAll() { return Array.from(arguments).reduce(function (a, b) { return a + b; }); }
由於Babel編譯時默認使用的是CommonJS的模塊規範,因此會看到轉譯後的代碼使用了require
方法來加載babel-polyfill
。這個在node環境下運行沒有問題,可是在瀏覽器環境下運行就會報錯,由於瀏覽器目前還不原生的支持模塊的加載。那在瀏覽器下怎麼使用babel-polyfill
呢?
咱們能夠把babel-polyfill
經過外部js的方式加載進來,而不是在js代碼裏進行引入:
<script src="node_modules/babel-polyfill/dist/polyfill.min.js"></script> <script src="lib/index.js"></script>
可是若是你打算在項目裏使用模塊,上面明顯不是很好的解決方案。下面咱們看看若是解決在瀏覽器環境下模塊的加載問題。
要在瀏覽器環境下加載依賴模塊,有不少方式,例如使用webpack
或者browserify
之類的打包工具(建議的方式,可是這裏咱們先不涉及)。或者咱們可使用瀏覽器端的模塊加載器進行加載,例如咱們使用AMD模塊規範進行編譯,而後用RequireJS進行加載。下面我使用SystemJS來作例子。
首先咱們安裝es2015-modules-systemjs
插件:
$ npm install babel-plugin-transform-es2015-modules-systemjs
而後修改配置文件,在plugins
裏添加插件:
{ "plugins": ["transform-es2015-modules-systemjs"] }
咱們修改下lib/index.js
,把addAll
方法導出爲模塊的方法:
import "babel-polyfill"; export function addAll() { return Array.from(arguments).reduce((a, b) => a + b); }
再次對文件進行編譯,編譯後的lib/index.js
變成這樣:
"use strict"; System.register(["babel-polyfill"], function (_export, _context) { "use strict"; return { setters: [function (_babelPolyfill) {}], execute: function () { function addAll() { return Array.from(arguments).reduce(function (a, b) { return a + b; }); } _export("addAll", addAll); } }; });
而後咱們須要在HTML裏引入system.js
。因爲SystemJS依賴於Promise
,它會加載目錄下system-polyfills.js
文件,因此咱們須要確保這個文件的存在。在加載system.js
後,咱們就可使用SystemJS進行模塊的加載了:
<html> <head> <meta charset="utf-8"> </head> <body> <script src="system.js"></script> <script> System.config({ baseURL: './lib', map: { 'babel-polyfill': './node_modules/babel-polyfill/dist/polyfill.min.js' } }); System.import('index.js').then(function(m) { console.log(m.addAll(1, 2, 3, 4, 5)); // 15 }); </script> </body> </html>
出於性能的考慮,也能夠用像Bluebird和es6-promise這樣的polyfill作替代,在
system.js
以前加載。
自此,咱們學習到了Babel的一些基礎用法,包括安裝和運行,以及配置和預設的用法,同時也初探了一些編譯後的文件的運行問題。可是要用好Babel,還有不少問題須要繼續探討,期待個人下一篇筆記。
https://babeljs.io/
https://github.com/thejamesky...
https://github.com/systemjs/s...