本文是依據 Babel 官網及網路參考資料逐步學習記錄的內容

Babel 這個壞男孩(發音似 Bad boy) 喜歡追求新潮的東西,同時內心是個文青,熱愛老東西。所以,當他接觸到新的內容,就會想盡辦法與舊事物融合~ 只能說個性實在完美

每當有新的javascript語法(例如ES2015-ECMAScript 6)出現,都只能靜待瀏覽器支援才能決定是否採取行動。 為了解決這樣的痛點,Babel就出現了。

Babel 具備了最新的javascript轉譯工具,能將最新的javascript轉換讓舊瀏覽器也能使用。

並且,默認支持 JSX ,因此在React使用時,可以直接搭配 Babel

在使用 Babel 之前,建議先對 ES2015 有一定的認識。

此外,babel可以在多種場景使用,因此可以依照開發的環境來尋找適合的使用方式

這裡我們會介紹幾個

一、 browserify & babel

這裡會說明如何在browserify同時自動使用babel功能

先建立 package.json

初始化環境,建立package.json

npm init

安裝,建立 node_modules

npm install

安裝

以global的方式安裝 browserify

npm install -g browserify

安裝 babel模組 babelify, 以及最新的轉碼規則 babel-preset-latest

npm install --save-dev babelify babel-preset-latest

開啟package.json 在起始加入 browserify,可以在執行browserify時,同時執行 babelify

{
  "browserify": {
    "transform": [["babelify", { "presets": ["latest"] }]]
  },
  ...
}

建立 ES6 js

建立一個main.js 內容輸入ES6 測試代碼

main.js

var myfn = foo => {
  return foo + ' world'
}

myfn('hello');

Browserify 自動執行 Babel 功能

直接執行 Browserify 並建立一個打包檔

browserify main.js > bundle.js -t babelify --presets [ latest ]

因為我們在 package.json 已經設定過,每次執行browserify都會自動加入babel 一起執行 package.json

{
  "browserify": {
    "transform": [["babelify", { "presets": ["latest"] }]]
  },
  ...
}

所以,直接執行browserify也是可以成功打包的 語法如下:

browserify main.js > bundle.js

打包完成後,開啟 bundle.js 內容應該就會把 ES6 風格直接轉換為正常 js

bundle.js

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

var myfn = function myfn(foo) {
  return foo + ' world';
};

myfn('hello');

},{}]},{},[1]);

二、Babel polyfill

Babel預設只會轉換出最新的javascript語法, 如果需要向下兼容,可以用 babel-polyfill 來達成

首先,安裝 babel-polyfill

npm install babel-polyfill

接著,在main.js 引用 models main.js

require('babel-polyfill');

var myfn = foo => {
  return foo + ' world'
}

myfn('hello');

進行browserify 之後,就會自動載入babel-polyfill

browserify main.js > bundle.js

三、使用擴充功能

上述都是 babel 的預設功能為主, 其實 babel還有相當多的擴充套件可以使用,例如 jsx,或者 babel-runtime 可以處理ES6 Generator會使用到的async

babel的擴充功能設定檔,可以寫在一個 .babelrc 檔案中,或者放在package.json

在示範安裝擴充套件前,先來了解一下 .babelrc 的基本格式

關於 .babelrc

其實,正常的建議是,一定要在根目錄位置,建立一個 .babelrc 檔案 並且擁有最基本格式

{
  "plugins": []
}

但是,根據官網所述,也可以直接將 .babelrc 直接放在 package.json 管理

用 package.json 管理 babelrc 設定

首先,請先複製.babelrc內容,並刪除 .babelrc

開啟 package.json,在 name, versin 之後,建立一個 babel key,再將原本的 babelrc設定寫入 package.json

{
  "name": "my-package",
  "version": "1.0.0",
  "babel": {
    // my babel config here
  }
}

使用擴充的方式

先安裝擴充

npm install babel-plugin-syntax-jsx

再將擴充的名稱添加到 .babelrc,之後,每次執行 babel 就會使用添加的擴充功能 .babelrc

{
  "plugins": ["syntax-jsx"]
}

或者,如果使用 package.json package.json

{
  "name": "babel_test",
  "version": "1.0.0",
  "babel":{
    "plugins": ["syntax-jsx"]
  },
  "browserify": {
    "transform": [
      [
        "babelify",
        {
          "presets": [
            "latest"
          ]
        }
      ]
    ]
  },
  ...
}

ES6 Generator需要的 Babel 安裝擴充

ES6 Generator會使用到的async,在網頁端會顯示出錯誤:

Generator regeneratorRuntime is not defined

因此,除了使用polyfill

require('babel-polyfill');

也要再額外安裝babel 的 transform-runtime 擴充

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

package.json

{
  "browserify": {
    "transform": [
      [
        "babelify",
        {
          "presets": [
            "latest"
          ]
        }
      ]
    ]
  },
  "name": "browserify",
  "version": "1.0.0",
  "babel": {
    "plugins": [
      [
        "transform-runtime",
        {
          "helpers": false,
          "polyfill": false,
          "regenerator": true,
          "moduleName": "babel-runtime"
        }
      ]
    ]
  },
  ...
}