你真的會用 Babel 嗎?

引入

這個問題是對本身的發問,但我相信會有不少跟我同樣的同窗。 對於 babel 的使用,近半年來一直停留在與 webpack 結合使用,以及在瀏覽器開發環境下。致使不少 babel 的包,我都不清楚他們是幹嗎的。好比 babel-register,還有 babel-runtime,各類 presets 的區別,transform-runtime 和 babel-polyfill 的區別,helpers 是幹嗎的。儘管網上的 babel 的教程不少了,可是解答本身的一些疑問,仍是要花費一些功夫。因此抽出時間來總結一下。若是你對於以上概念已經比較清楚了,就不須要往下看了。javascript

本次的 example 代碼都在 github 上,並且每一個文件夾都有詳細的 README,說明個人使用方式。能夠去參照一下用例的使用,並 clone 下來本身研究一下。前端

版本變化

說實話,從我作前端的時候,接觸 babel 的時候,就已是 babel 6 了,可是這不妨礙瞭解一下它的重大版本變化。 上一個版本 babel 5 是全家桶,包括各類package, plugins,儘量的想經過你的一次安裝,達到全能的效果。不過你如今安裝npm install babel,會獲得一個 warning。babel 6 是 2015年10月30號發佈,主要作了如下更新:java

  • 拆分紅幾個核心包,babel-core,babel-node,babel-cli...
  • 沒有了默認的轉換,如今你須要手動的添加 plugin。也就是插件化
  • 添加了 preset,也就是預置條件。
  • 增長了 .babelrc 文件,方便自定義的配置。

差很少了,我感受其餘的也不須要了解了。node

babel 裏面有好多的包,因此必須搞清楚他們都是幹嗎的,才能讓咱們更好的使用這個工具。react

babel-core

能夠看作 babel 的編譯器。babel 的核心 api 都在這裏面,好比 transform,主要都是處理轉碼的。它會把咱們的 js 代碼,抽象成 ast,即 abstract syntax tree 的縮寫,是源代碼的抽象語法結構的樹狀表現形式。咱們能夠理解爲,它定義的一種分析 js 語法的樹狀結構。也就是說 es6 的新語法,跟老語法是不同的,那咱們怎麼去定義這個語法呢。因此必需要先轉成 ast,去發現這個語法的 kind,分別作對應的處理,才能轉化成 es5.android

主要 api:webpack

var babel = require('babel-core');
var transform = babel.transform;
複製代碼
  • babel.transform(code: string, options?: Object)
transform("code", options) // => { code, map, ast }

複製代碼
  • babel.transformFile(filename: string, options?: Object, callback: Function)
var path = require('path');
babel.transformFile(path.resolve(__dirname) + "/test.js", {
  presets: ['env'],
  plugins: ['transform-runtime'],
}, function(err, result) {// { code, map, ast }
    console.log(result);
});
複製代碼
  • babel.transformFileSync(filename: string, options?: Object)
var result = babel.transformFileSync(path.resolve(__dirname) + "/test.js", {
  presets: ['env'],
  plugins: ['transform-runtime'],
});
console.log(result, 'res');

複製代碼
  • babel.transformFromAst(ast: Object, code?: string, options?: Object)

反轉,你把 ast 傳入,解析爲 code 代碼。ios

optionsgit

babel-cli

提供命令行運行 babel。也就是你能夠 babel filename 去對文件轉碼。 安裝的話es6

npm install --save-dev babel-cli

npm isntall babel-cli -g
複製代碼

使用對應就是

node_module/.bin/babel script.js --out-file script-compiled.js

babel script.js --out-file script-compiled.js
複製代碼

具體使用仍是看官方文檔吧,我就不搬文檔了。

babel-external-helpers

babel-cli 中的一個command,用來生成一段代碼,包含 babel 全部的 helper 函數。

首先咱們須要瞭解什麼是 helpers。babel 有不少輔助函數,例如 toArray函數, jsx轉化函數。這些函數是 babel transform 的時候用的,都放在 babel-helpers這個包中。若是 babe 編譯的時候檢測到某個文件須要這些 helpers,在編譯成模塊的時候,會放到模塊的頂部。 像這樣

(function(module, exports, __webpack_require__) {

function _asyncToGenerator(fn) { return function () {  }; } // 模塊頂部定義 helper

// some code 
// async 語法已經被 transform-async-to-generator 轉化,再利用 helper 函數包裝,消費 generator。
const func = (() => {
  var _ref = _asyncToGenerator(function* () {
    console.log('begin');
    yield new Promise(function (resolve) {
      setTimeout(function () {
        resolve();
      }, 1000);
    });
    console.log('done');
  });
})

})
複製代碼

可是若是多個文件都須要提供,會重複引用這些 helpers,會致使每個模塊都定義一份,代碼冗餘。因此 babel 提供了這個命令,用於生成一個包含了全部 helpers 的 js 文件,用於直接引用。而後再經過一個 plugin,去檢測全局下是否存在這個模塊,存在就不須要從新定義了。

使用:

  1. 執行 babel-external-helpers 生成 helpers.js 文件,
node_modules/.bin/babel-external-helpers > helpers.js
複製代碼

注意:示例代碼的包都是裝到項目中的,也就是本地。一樣你能夠全局安裝直接執行。 2. 安裝 plugin

npm install --save-dev babel-plugin-external-helpers
複製代碼
  1. 而後在 babel 的配置文件加入
{
  "plugins": ["external-helpers"]
}
複製代碼
  1. 入口文件引入 helpers.js
require('./helpers.js');
複製代碼

這樣就能夠啦,仍是能夠減小不少代碼量的。另外若是使用了 transform-runtime,就不須要生成 helpers.js 文件了,這個在後面的 babel-runtime 再說。

babel-node

也是 babel-cli 下面的一個 command,主要是實現了 node 執行腳本和命令行寫代碼的能力。舉兩個栗子就清楚了。

執行腳本

node 環境確定是不支持 jsx 的

// test.js
const React = require('react');
const elements = [1, 2, 3].map((item) => {
  return (
    <div>{item}</div>
  )
});

console.log(elements);
複製代碼

執行 test.js,會報錯,不認識這個語法。

node test.js //報錯
複製代碼

可是使用 babel-node 就能夠。

node_modules/.bin/babel-node --presets react test.js
複製代碼

--presets react 是參數,等同於

{
  "presets": ["react"]
}
複製代碼

執行正常。

node 命令行寫代碼

注意: 本文全部代碼示例,均在 node 版本 4.8.4 下執行。

寫個解構賦值的,直接運行 node,不支持。

node

運行 node_modules/.bin/babel-node --presets env

babel-node

獲得 a 的 value 是 1。

經過栗子基本已經介紹了 babel-node 的用法了,就是方便咱們日常開發時候,寫一些腳本的。因此它不適用於生產環境。另外,babel-node 已經內置了 polyfill,並依賴 babel-register 來編譯腳本。好,那 babel-register 是什麼呢

babel-register

npm install babel-register --save-dev
複製代碼

babel-node 能夠經過它編譯代碼,能夠了解到,它其實就是一個編譯器。咱們一樣能夠在代碼中引入它 require('babel-register'),並經過 node 執行咱們的代碼。

它的原理是經過改寫 node 自己的 require,添加鉤子,而後在 require 其餘模塊的時候,就會觸發 babel 編譯。也就是你引入require('babel-register')的文件代碼,是不會被編譯的。只有經過 require 引入的其餘代碼纔會。咱們是否是能夠理解,babel-node 就是在內存中寫入一個臨時文件,在頂部引入 babel-register,而後再引入咱們的腳本或者代碼?

舉個栗子,仍是 node 中執行 jsx,要經過 babel 編譯。咱們能夠把 jsx 的代碼 a.js 編譯完輸出到一個 b.js,而後 node b.js 也是能夠執行的。可是太麻煩,不利於開發。讓咱們看一下經過 register 怎麼用:

// register.js 引入 babel-register,並配置。而後引入要執行代碼的入口文件
require('babel-register')({ presets: ['react'] });
require('./test')
複製代碼
// test.js 這個文件是 jsx...
const React = require('react');
const elements = [1, 2, 3].map((item) => {
  return (
    <div>{item}</div>
  )
});
console.log(elements);
複製代碼
// 執行
$ node register.js
複製代碼

它的特色就是實時編譯,不須要輸出文件,執行的時候再去編譯。因此它很適用於開發。總結一下就是,多用在 node 跑程序,作實時編譯用的,一般會結合其餘插件做編譯器使用,好比 mocha 作測試的時候。

值得一提的是,babel-register 這個包以前是在 babel-core 下面的,因此也能夠 require('babel-core/register') 去引入,跟require('babel-register')是同樣的。可是,babel 的團隊把 register 獨立出來了,並且將來的某一天(升 7.0)會從 babel-core 中廢除,因此咱們如今最好仍是使用 babel-register 吧。babel-core/register.js

babel-runtime

npm install babel-runtime --save
複製代碼

這個包很簡單,就是引用了 core-js 和 regenerator,而後生產環境把它們編譯到 dist 目錄下,作了映射,供使用。那麼什麼是 core-js 和 regenerator 呢。 首先咱們要知道上面提到的 babel-core 是對語法進行 transform 的,可是它不支持 build-ints(Eg: promise,Set,Map),prototype function(Eg: array.reduce,string.trim),class static function (Eg:Array.form,Object.assgin),regenerator (Eg:generator,async)等等拓展的編譯。因此纔要用到 core-js 和 regenerator。

core-js

core-js 是用於 JavaScript 的組合式標準化庫,它包含 es5 (e.g: object.freeze), es6的 promise,symbols, collections, iterators, typed arrays, es7+提案等等的 polyfills 實現。也就是說,它幾乎包含了全部 JavaScript 最新標準的墊片。不過爲何它不把 generator 也實現了... 😁

// 好比,只不過須要單個引用
require('core-js/array/reduce');
require('core-js/object/values');
複製代碼

regenerator

它是來自於 facebook 的一個庫,連接。主要就是實現了 generator/yeild, async/await。

因此 babel-runtime 是單純的實現了 core-js 和 regenerator 引入和導出,好比這裏是 filter 函數的定義,作了一箇中轉並處理了 esModule 的兼容。

module.exports = { "default": require("core-js/library/fn/array/filter"), __esModule: true };
複製代碼

helpers

還記得提 babel-external-helpers 的時候,介紹 helpers 了嗎。babel-runtime 裏面的 helpers 就至關於咱們上面經過 babel-external-helpers 生成的 helpers.js。只不過它把每一個 helper 都單獨放到一個文件夾裏。這樣,配合 transform-runtime 使用的時候,須要用 helper 轉化的時候,就從 babel-runtime 中直接引用了。

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
複製代碼

文件結構:

文件結構

使用

能夠單獨引入require('babel-runtime/core-js/object/values');

不過這些模塊都作了 esModule 的兼容處理,也就是上面引入的模塊是{ "default": require("core-js/library/fn/array/filter"), __esModule: true }這樣的,要使用還得加上 .default。因此咱們期待的是,最好能有幫咱們自動處理的插件,babel-plugin-transform-runtime就是用來作這個的。這個咱們放到 plugin 去講。

babel-polyfill

npm install babel-polyfill --save
複製代碼

babel-runtime 已是一堆 polyfill 了,爲何這裏還有一個相似的包,它一樣是引用了 core-js 和 regenerator,墊片支持是同樣的。官網是這麼說的,babel-polyfill 是爲了模擬一個完整的ES2015 +環境,旨在用於應用程序而不是庫/工具。而且使用babel-node時,這個polyfill會自動加載(這個咱們在介紹 babel-node 的最後已經說了)。

也就是說,它會讓咱們程序的執行環境,模擬成完美支持 es6+ 的環境,畢竟不管是瀏覽器環境仍是 node 環境對 es6+ 的支持都不同。它是以重載全局變量 (E.g: Promise),還有原型和類上的靜態方法(E.g:Array.prototype.reduce/Array.form),從而達到對 es6+ 的支持。不一樣於 babel-runtime 的是,babel-polyfill 是一次性引入你的項目中的,就像是 React 包同樣,同項目代碼一塊兒編譯到生產環境。

使用

咱們結合 babel-register 去使用一下

// index.js
require('babel-core/register')({});
require('babel-polyfill'); // 是的,你要手動引入。
require('./async');
複製代碼
// async.js
async function a() {
  console.log('begin');
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, 1000)
  })
  console.log('done');
}
a();
複製代碼
$ node index.js
複製代碼

完美運行。 注意:babel-polyfill 只是爲當前環境全局下注入墊片,ES6 語法(E.g: arrow func,esModules)仍是要加入 plugins 去 transform 的。

plugins

要說 plugins 就不得不提 babel 編譯的過程。babel 編譯分爲三步:

  1. parser:經過 babylon 解析成 AST。
  2. transform[s]:All the plugins/presets ,進一步的作語法等自定義的轉譯,仍然是 AST。
  3. generator: 最後經過 babel-generator 生成 output string。

因此 plugins 是在第二步增強轉譯的,因此假如咱們本身寫個 plugin,應該就是對 ast 結構作一個遍歷,操做。

babel-plugin-transform-runtime

上面咱們知道,transform-runtime 是爲了方便使用 babel-runtime 的,它會分析咱們的 ast 中,是否有引用 babel-rumtime 中的墊片(經過映射關係),若是有,就會在當前模塊頂部插入咱們須要的墊片。試一下:

npm install babel-plugin-transform-runtime
複製代碼
// 編譯前
console.log(Object.values({ 1: 2 }));

複製代碼
node_modules/.bin/babel --plugins transform-runtime values.js
複製代碼
// 編譯後
'use strict';

var _values = require('babel-runtime/core-js/object/values');

var _values2 = _interopRequireDefault(_values);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

onsole.log((0, _values2.default)({ 1: 2 }));
複製代碼

另外,它還有幾個配置

// 默認值
{
  "plugins": [
    ["transform-runtime", {
      "helpers": true,
      "polyfill": true,
      "regenerator": true,
      "moduleName": "babel-runtime"
    }]
  ]
}
複製代碼

若是你只須要用 regenerator,不須要 core-js 裏面的 polyfill 那你就能夠在 options 中把 polyfill 設爲 false。helpers 設爲 false,就至關於沒有啓用 babel-plugin-external-helpers 的效果,好比翻譯 async 的時候,用到了 asyncToGenerator 函數,每一個文件還會從新定義一下。moduleName 的話,就是用到的庫,你能夠把 babel-runtime 換成其餘相似的。

transform-runtime 對比 babel-polyfill

其實經過上面的介紹咱們已經瞭解他們是幹什麼的了,這裏再稍微總結區分一下吧。我在這裏把 babel-runtime 和 babel-plugin-transform-runtime 統稱爲 transform-runtime,由於一塊兒用才比較好。

  • babel-polyfill 是當前環境注入這些 es6+ 標準的墊片,好處是引用一次,再也不擔憂兼容,並且它就是全局下的包,代碼的任何地方均可以使用。缺點也很明顯,它可能會污染原生的一些方法而把原生的方法重寫。若是當前項目已經有一個 polyfill 的包了,那你只能保留其一。並且一次性引入這麼一個包,會大大增長體積。若是你只是用幾個特性,就不必了,若是你是開發較大的應用,並且會頻繁使用新特性並考慮兼容,那就直接引入吧。
  • transform-runtime 是利用 plugin 自動識別並替換代碼中的新特性,你不須要再引入,只須要裝好 babel-runtime 和 配好 plugin 就能夠了。好處是按需替換,檢測到你須要哪一個,就引入哪一個 polyfill,若是隻用了一部分,打包完的文件體積對比 babel-polyfill 會小不少。並且 transform-runtime 不會污染原生的對象,方法,也不會對其餘 polyfill 產生影響。因此 transform-runtime 的方式更適合開發工具包,庫,一方面是體積夠小,另外一方面是用戶(開發者)不會由於引用了咱們的工具,包而污染了全局的原生方法,產生反作用,仍是應該留給用戶本身去選擇。缺點是隨着應用的增大,相同的 polyfill 每一個模塊都要作重複的工做(檢測,替換),雖然 polyfill 只是引用,編譯效率不夠高效。

另外,關於 babel-runtime 爲何是 dependencies 依賴。它只是一個集中了 polyfill 的 library,對應須要的 polyfill 都是要引入項目中,並跟項目代碼一塊兒打包的。不過它不會都引入,你用了哪一個,plugin 就給你 require 哪一個。因此即便你最終項目只是 require('babel-runtime/core-js/object/values')其中的一個文件,可是對於這包來講,也是生產依賴的。

注意:babel-polyfill 並非必定會污染全局環境,在引入這個 js,並運行的時候,它會先判斷當前有沒有這個方法,在看要不要重寫。如上圖

presets

各類配置 plugin 實在是費勁,es6+ 編譯要加入好多 plugins,好比爲了在 node 中使用 esmodule,要把 esmodule 轉化成 commomjs,使用 transform-es2015-modules-commonjs,還有 asyncToGenerator,React jsx轉化等等,不只要裝好多,還要配好多。

presets 就是 plugins 的組合,你也能夠理解爲是套餐... 主要有

大部分的 presets 我以爲都不須要介紹了,官網上寫的比較詳細。並且 babel-preset-lastet(包括 es2105,es2016,es2017)跟默認狀況下的 env 是同樣的,也就是說包括 lastest 在內,這四個 presets 都要被 babel-preset-env 代替。即:

{ "presets": ["latest"] } === { "presets": ["env"] }

複製代碼

babel-preset-env

這個 preset 真是神器啊,它能根據當前的運行環境,自動肯定你須要的 plugins 和 polyfills。經過各個 es標準 feature 在不一樣瀏覽器以及 node 版本的支持狀況,再去維護一個 feature 跟 plugins 之間的映射關係,最終肯定須要的 plugins。

preset-env 配置

詳情:

{
  "presets": [
    [
      "env",
      {
        "targets": { // 配支持的環境
          "browsers": [ // 瀏覽器
            "last 2 versions",
            "safari >= 7"
          ],
          "node": "current"
        },
        "modules": true,  //設置ES6 模塊轉譯的模塊格式 默認是 commonjs
        "debug": true, // debug,編譯的時候 console
        "useBuiltIns": false, // 是否開啓自動支持 polyfill
        "include": [], // 老是啓用哪些 plugins
        "exclude": []  // 強制不啓用哪些 plugins,用來防止某些插件被啓用
      }
    ]
  ],
  plugins: [
    "transform-react-jsx" //若是是須要支持 jsx 這個東西要單獨裝一下。
  ]
}
複製代碼

主要介紹 debug 和 很好用的 useBuiltIns 吧。

debug

開啓debug後,編譯結果會獲得使用的 targets,plugins,polyfill 等信息

Using targets:
{
  "chrome": "59",
  "android": "4.4.3",
  "edge": "14",
  "firefox": "54",
  "ie": "10",
  "ios": "10",
  "safari": "7",
  "node": "4.8.4"
}

Modules transform: commonjs

Using plugins:
  check-es2015-constants {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  transform-es2015-arrow-functions {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  transform-es2015-block-scoped-functions {"android":"4.4.3","ie":"10","safari":"7"}
  transform-es2015-block-scoping {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  ...
Using polyfills:
  es6.typed.array-buffer {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  es6.typed.int8-array {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  es6.typed.uint8-array {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  es6.typed.uint8-clamped-array {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  es6.typed.int16-array {"android":"4.4.3","ie":"10","safari":"7","node":"4.8.4"}
  ...
複製代碼

useBuiltIns

env 會自動根據咱們的運行環境,去判斷須要什麼樣的 polyfill,並且,打包後的代碼體積也會大大減少,可是這一切都在使用 useBuiltIns,並且須要你安裝 babel-polyfill,並 import。它會啓用一個插件,替換你的import 'babel-polyfill',不是整個引入了,而是根據你配置的環境和我的須要單獨的引入 polyfill。 我嘗試了一下是否真的有效,下面是個人對比實驗過程:

step1: 首先是這樣一段測試編譯的代碼,有 jsx,Object.values,async。env 的配置除了 useBuiltIns 都跟上面的配置同樣。而後經過 webpack + babel-loader 打包,生成 build.js

require('./async');
// import 'babel-polyfill';

const React = require('react');
const elements = [1, 2, 3].map((item) => {
  return (
    <div>{item}</div>
  )
});

console.log(elements);

async function a() {
  console.log('begin');
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, 1000)
  })
  console.log('done');
}
a();

console.log(Object.values({ 1: 2 }));

console.log(Array.isArray([]));

複製代碼

step2: 而後經過設置不一樣的參數,打包,獲取 build.js,並執行。獲得下表

preset-env 條件下 useBuiltIns: true
不引入 polyfill build.js 代碼體積 158k,node build.js 執行報錯。
引入 polyfill build.js 體積 369k,執行經過。包確實減少了。
  • 用 preset-es2015,並引入 polyfill plugins 多加一個 transform-regenerator,這方面確實不如 env 方便一些。 體積 418k,執行經過。不方便在要配好多 plugins。

具體的過程、截圖猛戳 這裏

最終的結論就是,使用了 useBuiltIns 確實體積變小了,比直接 import 'babel-polyfill' 好了許多。

step3: 而後... 我又試了一下 env 下,使用 transform-runtime。在不加 useBuiltIns,不引入 babel-polyfill 的狀況下。build.js 體積234k,執行經過。

咦,這樣好像體積更小啊。別忘了,咱們的 babel-polyfill 是配置了執行環境的,經過環境看你須要哪些 polyfill。而 transform-runtime,是發現咱們代碼須要什麼 polyfill,固然會少不少了。因此,又回到了用哪一個的問題... 😓 參考上面的總結。

then

helpers 的問題。開發項目,使用 preset-env,並 import 'babel-polyfill',可是 helpers 好像沒有地方配置。並且我試了兩個文件分別用 async 函數,編譯後每一個模塊都定義了 asyncToGenerat 函數,這種狀況下我以爲最後就是本身生成一個 helpers.js 文件了。

總結

如今看起來開發大點的項目,最好用的配置應該就是 preset-env,肯定本身的運行環境,若是有須要,再加上 useBuiltIns,並生成一份 helpers.js 的文件。不過,一切仍是看你的需求,個人前提是開發大點的「項目」,不過了解了這些東西,你會作出本身的選擇。

babel 的配置

目前 babel 官方推薦是寫到 .babelrc 文件下,你還能夠在 package.json 裏面添加 babel 字段。不用配置文件的話,能夠把配置當作參數傳給 babel-cli

  • .babelrc
{
  "presets": [
    "env"
  ],
  "plugins": [
    ["transform-runtime", {
      "helpers": true,
      "polyfill": true,
      "regenerator": true,
      "moduleName": "babel-runtime"
    }]
  ]
}
複製代碼
  • 寫到 package.json
"babel": {
  "presets": [
    "env"
  ],
}
複製代碼
  • babel cli
babel script.js --plugins=transform-runtime --presets=env
複製代碼

配合其餘工具

webpack

比較經常使用,除了 babel 本身的包,多裝一個 babel-loader 配合 webpack 使用。並在 webpack.config.js 中加入 loader 的配置

module: {
    rules: [
      {
        test: /\.js$/,
        use: ['babel-loader'],
        exclude: /node_modules/,
      }
    ]
  }
複製代碼

mocha

項目裏的代碼都是用 es6+ 寫的,可是作單元測試的時候,測試框架並不認識你的什麼 esModule,es6+ 的一些語法,mocha 是 node 程序,因此你要把 esModule 轉化成 commomjs 之類的。

mocha 是支持編譯器的,經過 --compilers 指定,這裏咱們用 babel,舉個栗子

// 求和函數 add.js
const add = (x, y) => x + y;

export default add;

複製代碼
// 測試腳本 add.test.js
import { expect } from 'chai'; // chai 是斷言庫
import add from './add';

describe('es6 兩數相加', () => {
  it('2 + 4 = 6', () => {
    expect(add(2, 4)).equal(6);
  })
});

複製代碼
./node_modules/mocha/bin/mocha --compilers js:babel-register add.test.js
複製代碼

由於 mocha 終究是在跑 node 程序的,適用於實時編譯,因此能夠用 babel-register 作編譯器。

最後

總結這些東西花了我兩三天的時間,雖然搞清楚了這些包是幹嗎的,可是又在想到底應不該該花時間研究這些,工具始終是用來使用的,對於 babel 來講更應該研究的是它對 ast 的處理方式?不過看到本身的產出,我以爲是有必要的,另外,由於對工具更進一步的瞭解,才能更好的在項目中使用它們,而不是一頓照搬,代碼是能夠正經常使用了,可是可能會有不少不須要的東西,致使代碼體積變大。「割雞焉用牛刀」,我以爲仍是須要有精益求精的精神。但願對你有所幫助。

個人我的博客地址 https://github.com/sunyongjian/blog ,歡迎訂閱,star,謝謝。

相關文章
相關標籤/搜索