Babel知識體系淺談

我我的正在寫Node.js的系列學習筆記node-learning-manual,包含了Node.js的基本模塊和工程化相關的知識, 若是對你有幫助,請點個start,您的支持是對我最大的鼓勵。前端

前言

前端發展到如今,可謂是混亂至極,已經遠遠超出我對前端所謂一把jQuery抄起來就是懟,vue

Webpack, babel, node.js, react, vue各類工程框架,構建工具你不會點好像都不算是個合格的node

前端工程師,語法相關的ES6/7老是繞不過Babel,這篇文章就是直接討論Babel。react

本文只要圍繞如下幾塊來講:git

  1. Babel編譯過程介紹
  2. Babel插件及預設
  3. Babel-register在項目中的使用
  4. babel的polyfill引入機制
  5. babel在前端工程的定位

Babel編譯過程介紹

  1. 核心包github

    // 暴露babel.transform方法來編譯source code
    babel-core
    // 語法字符串解析parser
    babylon
    // 結合plugins遍歷AST語法樹
    babel-traverse
    // 生成最後的編譯字符串
    babel-generator
    複製代碼
  2. babel編譯流程shell

    input string
    -> babylon parser
    -> AST
    -> babel-traverse  //使用plugins遍歷AST語法樹
    -> AST
    -> babel-generator
    -> output string
    複製代碼

Babel是一個JavaScrpit的編譯器,從宏觀的角度來看,它有三個運行階段:解析,轉化,生成。基本上若是不設置配置文件.babelrc,Babel運行的結果即是 const babel = code => code ,經過讀取代碼,最後生成同樣的代碼。Babel的最核心的概念即是插件,經過在配置文件 .babelrc中添加不一樣的插件基本能夠作全部的事情。npm

Babel插件(plugins)及預設(presets)

首先聊聊插件與預設的關係,官方預設即是由官方評審維護的一系列插件組合。插件與預設的關係即是父子集合的關係。api

每一年babel都會評估當年的插件,babel-preset-env 取代了 es2015, es2016, es2017 以及最新的代碼bash

Babel-register在項目中的使用

babel-register的設計思想很是厲害,簡單的來講就是require hook。也是babel常見的一種使用方法。

這種方法只須要引入文件就能夠運行 Babel,或許能更好地融入你的項目設置。

讓咱們先在項目中建立index.js文件

// index.js
console.log("hello world");
複製代碼

接着須要咱們安裝babel-register

$ npm install i -D babel-register
複製代碼

接着,在項目中建立 register.js 文件並添加以下代碼:

require("babel-register");
require("./index.js");
複製代碼

而後咱們只須要啓動 node register.js 即可,經過修改require function,對全部的經過require引入的代碼先通過babel編譯一遍,再給到runtime執行。

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

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

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

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

而後只須要在文件頂部導入 polyfill 就能夠了:

import "babel-polyfill";
複製代碼

因此個人我的建議是按需引入core-js的模塊而不是整個babel-polyfill bundle,來對ES6/7新增的數據對象和方法作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的出現讓開發者能夠自由的採用ES6/7的語法來編寫JS項目,極大的豐富了開發 (browser, node) 層面的JS語言特性。

babel的AST parser、polyfill、 register一塊兒完成了babel體系對JS的完備解決方案。

參考資料

babel 知識體系漫遊

babel handbook

babel docs

我我的正在寫Node.js的系列學習筆記node-learning-manual,包含了Node.js的基本模塊和工程化相關的知識, 若是對你有幫助,請點個start,您的支持是對我最大的鼓勵。

相關文章
相關標籤/搜索