babel 相關名詞簡介
babel 是現代前端工程師都不陌生的工具,它可以將 ES6 (+) 的語法轉換為 ES5 甚至是更低的版本,利用 babel 可以讓開發者即刻享受到 ES6 語法所帶來的便利性。 然而許多 babel 相關的名詞卻常常困擾想要入門的新手們,因此利用本文簡介那些與 babel 相關的名詞,以 babel 6 為主。
本篇將會會介紹到:
- .babelrc
- babel-cli (with babel-node)
- babel-preset vs. babel-plugin
- babel-register
- babel-polyfill
- babel-plugin-transform-runtime & babel-runtime
- babel-loader
- babel-eslint
本文用意並非完善的介紹整個 babel 生態系,而是作者整理自己常見且容易搞錯的 babel 相關名詞。
一、.babelrc
這是 babel
這個工具需要用到的設定檔,以下所介紹到的各項都需要該設定檔讓 babel 有轉換的依據。
方法一:
直接寫獨立的 .babelrc
檔,一個基本的格式如下:
{
"presets": ["es2015"]
}
方法二:
直接寫進 package.json
檔
{
"name": "my-package",
"version": "1.0.0",
"babel": {
// your babel config here
}
}
註:方法二雖然可以這樣寫,但不建議使用,因為在 react-native 會出現已知的問題。
二、babel-cli
利用 npm 安裝 babel-cli 將會同時註冊 babel
和 babel-node
兩個最常使用的指令。
$ npm install babel-cli --save-dev
利用上述指令安裝在 project 的目錄底下。
babel
可以直接在終端機利用 babel
指令做 ES6 的語法轉換,
常用的情景為將 src
資料夾 build 成 lib
資料夾,
身為 library 開發者,以不要預設使用者有 ES6 的環境為佳,
上述簡單的指令如下:
$ babel src -d lib
若需更多參數,請參考官方教學。
babel-node
可以利用 babel-node myEs6.js
直接運行 ES6 的 code,
當然需要 .babelrc 檔還有相關的 presets 或是 plugins 做為 babel 轉換的依據。
而 babel-node
執行的時候會預設載入 babel-polyfill
使用,
因此會佔大量的記憶體空間,官方不建議在 production 環境使用。
三、babel-preset vs. babel-plugin
presets 和 plugins 這兩個 key 在 .babelrc
檔內會很常看到,
其中的差異便是一個 preset 可以包含其他不同 presets 或是不同的 plugins。
例如 babel-preset-es2015
當中包含了
transform-es2015-arrow-functions
transform-es2015-block-scoped-functions
等 21 個不同的 plugins。
順序問題
babel 在執行 transform 的過程,會 plugins 先載入,且按照由上往下(由左向右)的順序載入, 但是要注意的事情,presets 會在 plugins 之後,然後載入的順序是由下往上(由右向左)的反向順序。
stage
babel 針對 stage 有實作幾個不同的 presets,包含了
- preset-stage-0
- preset-stage-1
- preset-stage-2
- preset-stage-3
stage 數字越大的 preset 所包含的 plugins 代表即將進入 ECMA262 standard, TC39 Process, 官方預設的範例 stage 0 的 preset 使用就是因為其包含了 stage 1, 2, 3 的 presets, 而許多開發者直接用 stage 0,會把全部 stage 都載入,建議花時間了解各個 preset-stage 分別載入哪些 plugins 為佳。
stage 是會隨著時間演進,在不同的階段所看到的 stage 內容可能都不一樣。
四、babel-register
當載入 babel-register
後,其接下來的 es6 語法都可以被設定的 .babelrc 做轉換,
載入的方式有兩種:
方法一:
額外建立一個進入點檔案,由於在這個進入點 node 並不知道 es6 語法,
因此於此需要利用 require('babel-register')
的方式載入
進入點檔名以 entry.js
為例:
require('babel-register');
require('./yourEs6Index');
因此未來執行 node entry.js
就可以利用 babel-register
動態載入的方式進行轉換語法。
方法二:
在終端機執行 node
的時候,直接利用 -r
參數帶入 babel-register
,-r
等於 --require
代表 module to preload
$ node -r babel-register yourEs6Index.js
五、babel-polyfill
什麼是 polyfill
?
wiki: In web development, a polyfill is code that implements a feature on web browsers that do not support the feature.
因此 babel-polyfill
顧名思義就是 babel 幫我們做了一些現階段還沒有被各家瀏覽器通用支援的 feature,好讓我們在現階段就可以利用一些未來原生的語法,例如:Promise
, Array.from
, Object.assign
, Array.includes
等。
像是 Chrome 對於 es6 的支援度一直以來都蠻高的,但是並非每家瀏覽器廠商都能支援,因此需要有 polyfill。
babel-node
當利用 babel-node 去運行 js 檔的時候,會預設載入 babel-polyfill
,
因此你即可利用 babel-node run 一個帶有 promise 的 js 檔,
而不需再另外 require bluebird
等套件。
babel-polyfill
主要 includes 了 regenerator runtime 和 core-js。
regenerator runtime
就是將 generator/async 轉換成 es5 語法,而 core-js
是 Modular standard library for JavaScript 集合,詳細請參閱連結。
六、babel-plugin-transform-runtime & babel-runtime
在做轉換的時候,若利用 babel-polyfill
會做 global scope,所以當你今天是要做 lib/tool 模式,沒辦法控制你的運行環境,則不適合利用 babel-polyfill,需要用 babel-plugin-transform-runtime
為佳。
babel-plugin-transform-runtime
會把多個檔案 reference 到babel-runtime
這個 package,因此當你使用transform-runtime
就一定要裝babel-runtime
babel-plugin-transform-runtime
的轉換機制也是 alias 到core-js
,就和babel-polyfill
一樣,所以不用再 requirebabel-polyfill
- 官方建議安裝方法如下: transform 安裝進 devDependencies
$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save babel-runtime
七、babel-loader
loader
是 webpack
用來載入各種不同類型檔案的套件,而 babel-loader
讓 webpack 可以用來執行 babel 轉換的的一種套件。
利用 babel-loader
可以利用 webpack 打包時候同時進行 babel 的轉換,以下是簡單範例檔:
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel'],
exclude: /node_modules/,
},
],
},
因為 babel-loader
的速度很慢,官方建議把 node_modules
exclude 掉。
八、babel-eslint
ESLint
堪稱是近代偉大的 linter 發明之一,它可以讓使用者高度客製化的 parser 語法,而目前原生的 ESLint 支援的語法有 ES6/ES7
, JSX
, and object rest/spread
,如果你用到的更多 babel 語法則需要 babel-eslint 來幫忙。
$ npm install eslint@3.x babel-eslint@6 --save-dev
.eslintrc 範例檔
{
"parser": "babel-eslint",
"rules": {
"strict": 0
}
}
結論
當然 babel 的套件不僅僅如此,還有 babelify, babili 等許多相關工具尚未有時間介紹,本篇所提及的介紹希望能對於部分開發者有幫助。 若有不清楚或者會誤導讀者的方向,還請不吝指教。