一天疾速相識Babel

在做項目中一向運用的是腳手架搭建的環境,一向沒有細緻的去相識 babel 這一東西,這周末抽出一天時刻經由過程官網另有種種博客文章算是相識了一些內容,最少能夠在項目中本身完成 .babelrc 的設置了。

這篇文章就是把本身的明白和找到的優異文章的內容做一融會和整頓,明白有誤的處所還請人人批評指正~

因為主假如面臨項目,所以本文內容重要照樣繚繞 .babelrc 睜開,與babel 相干的其他東西無關。

Babel 是什麼?

Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in old browsers or environments.

因為瀏覽器對 ECMAScript 的支撐各有差別,因而 Babel 是一個用來將 ES6 版本以上代碼轉為 ES5 版本代碼的東西,從而使得編寫的代碼能夠在指定的環境下運轉。

.babelrc 設置文件

在項目中我們運用 Babel 做轉碼平常運用設置文件的情勢。Babel 的設置文件名為 .babelrc 而且一般放在項目根途徑下,其花樣大抵以下:

{
  "env": {
    "production": {
      "presets": [],    // 轉碼劃定規矩
      "plugins": [],    // 插件
      "ignore": ["node_modules/"]    // 轉碼時刻疏忽的文件
    }
  }
}

這裏的 env 的值獲得是項目中的 process.env.BABEL_ENV 假如該值找不到,則取 process.env.NODE_ENV 末了假如該值還找不到,則設為 development

處置懲罰遞次

  1. plugins 優先於 presets
  2. plugins 從數組第一個到末了一個舉行編譯
  3. presets 從數組末了一個到第一個舉行編譯 ,這個目標重要為了向後降級

presets

presets 用於設置轉碼的劃定規矩,經常使用的 presetsenvstage-x

關於 env 後文會提到,先來看看 stage-x

stage-x 是新特徵歸入範例所經由的幾個階段,
x 值越小,示意階段越靠後,靠後的階段包含前面的一切內容,即
stage-0 包含
stage-1/2/3 的一切內容

《一天疾速相識Babel》

上圖是 stage-2index.js 文件,能夠看到个中直接援用了 stage-3 的一切特徵。

實際上來講,presets 就是 plugins 的鳩合,假如沒有 preset 也是能夠完成代碼轉換事情的,以下。

{
  "plugins": [
    "check-es2015-constants",
    "es2015-arrow-functions"
  ]
}

然則因為這麼設置過於煩瑣,因而 Babel 把一些屬於一致範例的 transform-plugins 劃歸到一個 presets 中,如許有了 presets 就不必再一個一個地導入 transform-plugins 了。

babel-polyfill & babel-runtime

Babel 默許只轉換 JS 語法,而不轉換新的 API ,新範例中的全局對象和定義在這些全局對象上的要領都不會轉碼,這些 API 許多,詳細參考 definitions.js

這就致使了 babel-polyfillbabel-runtime 的發生

babel-polyfill

  1. 把一切的 polyfill 一次性悉數引入,不論你在項目中是不是真正用到
  2. 污染全局對象,能夠激發爭執。假如你開闢的是一個運用項目,那末這一點能夠臨時疏忽,然則假如你開闢的是一款插件或許他人未來引入的包,那末很有能夠會給運用者帶來不方便
  3. 因為須要在本身的代碼之前運轉這些 polyfill 所以該包應該被增加到 dependency
  4. webpack 連繫運用時刻須要放在 entry 數組中 entry: ["babel-polyfill", "app.js"]

babel-runtime

babel-polyfill 的一次性引入差別,babel-runtime 支撐本身手動引入 helper 函數,來完成對某一 API 的轉碼。它更像是一個個疏散的 polyfill 模塊。

不言而喻 babel-runtime 的瑕玷之一就是每次運用 API 的時刻,都須要我們舉行手動引入,很貧苦;另外,在代碼中直接引入 helper 函數,會致使打包的文件中湧現許多反覆 helper 代碼。因而如今實際事情中會運用 babel-runtime + babel-plugin-transform-runtime 的情勢

babel-plugin-transform-runtime

這個包能夠幫我們完成 babel-runtimehelper 函數的自動引入,而且它還做了公用要領的抽離,你引入的函數都是援用自一個處所,就避免了反覆的代碼

該包依靠 babel-runtime ,這也是為何我們在運用 webpack 設置 babel 的時刻,只須要裝置 babel-plugin-transform-runtime 的緣由,
devDependencies 里只看見了 babel-plugin-transform-runtime

該插件重要做了三件事:

  1. 當你運用 generators/async 要領、函數時自動挪用 babel-runtime/regenerator
  2. 當你運用 ES6 的 Map 或許內置的東西時自動挪用 babel-runtime/core-js
  3. 移除內聯 babel helpers 並替換運用 babel-runtime/helpers 來替換

長處

  1. 不會污染全局變量
  2. 屢次運用只打包一次
  3. 依靠按需引入,無反覆引入
  4. 合適編寫庫範例的代碼

瑕玷

  1. 不支撐實例化的要領 'foobar'.includes('foo') 不能轉化

設置

平常直接默許就行,不須要對該插件舉行設置

{
  "plugins": [
    ["transform-runtime", {
      "polyfill": true,       // 是不是把新特徵轉換為非全局的 polyfill
      "helpers": true,        // 是不是用模塊中的 helpers 替換內聯 helpers
      "regenerator": true,    // 是不是把生成器函數轉換為非全局的 polyfill
      "moduleName": "babel-runtime"  // 導入 helpers 的時刻的模塊途徑
    }]
  ]
}

一次小測試

.babelrc

《一天疾速相識Babel》

轉碼前的 a.js

《一天疾速相識Babel》

轉碼后的 a-compiled.js

《一天疾速相識Babel》

能夠看到實例要領 "foo".includes('f') 並沒有被轉換

再來一個小測試

.babelrc

《一天疾速相識Babel》

轉碼前的 b.js

《一天疾速相識Babel》

運用 babel 轉碼后,Set 轉碼勝利,而且能夠看到在轉碼后的文件中,打印的並非原生的 Set ,而是 babel 為我們包裝的一個替換原生 Set 的模塊,避免了全局污染。

《一天疾速相識Babel》

當我們把 .babelrc 中改成 polyfill: false 時,再次對 b.js 轉碼,轉碼后,語句沒有被處置懲罰。打印的就是原生的 Set ,污染了全局變量。

《一天疾速相識Babel》

假如須要對實例要領舉行轉碼,能夠這麼來,固然你須要在 .babelrc 里改成 polyfill: true ,不然沒有這個 polyfill 基礎沒有這些要領。

轉碼前:

《一天疾速相識Babel》

轉碼后:

《一天疾速相識Babel》

假如非要在不支撐的環境下運用實例要領的話,就還得藉助 babel-polyfill 了(或許你本身完成一個)。不過彷佛現在瀏覽器端對這類諸如 includesrepeat 之類的要領支撐的還不錯了。

babel-preset-env

Without any configuration options, babel-preset-env behaves exactly the same as babel-preset-latest (or babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017 together).

起首官網上給了公式

沒有任何設置的 env = latest = es2015 + es2016 + es2017

babel-preset-env 因為其天真的設置和周全的功用,被官網引薦,同時也是現在運用很頻仍的 presets

設置項

targets

供應須要支撐的環境信息,版本等,默許為 {}

spec

經由過程捐軀轉換時刻來支撐該 preset 的更多範例兼容性,默許為 false

loose

preset 中的插件開啟鬆懈轉換

鬆懈形式

長處:轉換的代碼越發簡約,沒有為了靠近 ES6 而增加的冗雜邏輯,文件更小,運轉速率更快,兼容性更好

瑕玷:直接運用原生 ES6 能夠會有題目

平常不引薦運用鬆懈形式

簡樸來講,鬆懈形式轉換后的代碼很輕易就可以看懂,而且很像我們日常平凡寫的代碼,但這類不嚴謹的轉換能夠會形成題目,所以在開闢中是不引薦的。

感受一下:

轉碼前:

《一天疾速相識Babel》

轉碼后(一般):

《一天疾速相識Babel》

轉碼后(鬆懈):

《一天疾速相識Babel》

modules

把 ES6 模塊語法轉為另一個模塊範例,默許 commonjs

如今的
webpack 4.x 已把模塊一致的使命完成了,所以這裏就不須要
babel 來做了,所以在
vue-cli 這類用
webpack 打包的腳手架里,你會看到
.babelrc 文件中有
module: false 這就是為了防備與
webpack 爭執

include

指定一組老是包含的插件,當原生完成有題目,或存在不支撐或支撐不好的特徵時刻運用,默許為 []

include
exclude 只事情於包含在
preset 里有的插件中,假如要運用
preset 里不包含的插件,直接填在
.babelrc
plugins

exclude

指定一組老是不包含的插件,默許為 []

useBuiltIns

默許為 false
會啟用一個插件來依據運用情況去按需加載 polyfill 來替換 import "babel-polyfill" 語句

其他 Babel 東西

一切的東西發起都在項目中裝置,而不是採納全局裝置

  1. babel-cli 用於敕令行轉碼
  2. babel-node 追隨 babel-cli 裝置,可直接運轉 ES6 代碼,因為採納這類體式格局是及時轉碼的,轉碼的一切東西都存在內存中,發生大批資本斲喪因而只合適在開闢中運用
  3. babel-register 改寫 require 敕令,每次運用 require 加載 js 文件時刻,就會先轉碼,因為是及時轉碼,只合適在開闢環境運用
  4. babel-core 供應 Babel 的 API,以後能夠採納編程體式格局運用 Babel

參考鏈接

  1. Babel · The compiler for next generation JavaScript
  2. 對babel-transform-runtime,babel-polyfill的一些明白
  3. Babel 入門教程 – 阮一峰的網絡日誌
  4. babel-polyfill的幾種運用體式格局
  5. Babel筆記 – Tony’s Blog
  6. Babel的運用
  7. Babel 6 鬆懈形式
    原文作者:breezymelon
    原文地址: https://segmentfault.com/a/1190000015373911
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞