babel基礎配置

小閒發表於2019-01-25

babel

標籤(空格分隔): babel


babel

  • Babel是一個廣泛使用的轉碼器,可以將ES6程式碼轉為ES5程式碼,從而在現有環境執行。
  • Babel 會在正在被轉錄的檔案的當前目錄中查詢一個 .babelrc 檔案。 如果不存在,它會遍歷目錄樹,直到找到一個 .babelrc 檔案,或一個 package.json 檔案中有 “babel”: {}
  • babel6將babel全家桶拆分成了許多不同的模組(rc是run command的縮寫)

依賴

babel-loader:使用es6或載入模組時,對es6程式碼進行預處理,轉為es5語法。
babel-core:允許我們去呼叫babel的api,可以將js程式碼分析成ast(抽象語法樹),方便各個外掛分析語法進行相應的處理.
babel-preset-env:推薦preset,比如es2015,es2016,es2017,latest,env(包含前面全部)
babel-polyfill:它效仿一個完整的ES2015+環境,使得我們能夠使用新的內建物件比如 Promise,比如 Array.prototype.includes 和生成器函式(提供給你使用 regenerator 外掛)。為了達到這一點, polyfill 新增到了全域性範圍,就像原生型別比如 String 一樣。
babel-runtime babel-plugin-transform-runtime:這個外掛能自動為專案引入polyfill和helpers

presets

  • babel5會預設轉譯ES6和jsx語法,babel6轉譯的語法都要在perset中配置,preset簡單說就是一系列plugin包的使用。
  • 預設就是一系列外掛的集合,把之前的引數儲存為一個預設,下次就能直接使用。
  • 基礎配置如下:(設定轉碼規則和外掛)
{
  "presets": [],
  "plugins": []
}
  • presets欄位設定轉碼規則,官方提供以下的規則集,按需安裝。
  • 可以看到提案在進入stage3階段時就已經在一些環境被實現,在stage2階段有babel的實現。
# ES2015轉碼規則
babel-preset-es2015
# react轉碼規則
babel-preset-react
# ES7不同階段語法提案的轉碼規則(共有4個階段)
babel-preset-stage-0
babel-preset-stage-1: draft - 必須包含2個實驗性的具體實現,其中一個可以是用轉譯器實現的,例如Babel。
babel-preset-stage-2: candidate - 至少要有2個符合規範的具體實現。
babel-preset-stage-3

配置:

{
    "presets": [
      "es2015",
      "stage-2"
    ],
    "plugins": []
  }

babel-preset-env

此段內容來自於babel到底該如何配置?

  • 上面這些preset官方現在都已經不推薦了,官方唯一推薦preset:babel-preset-env
  • 這款preset能靈活決定載入哪些外掛和polyfill
// cnpm install -D babel-preset -env
{
    "presets": [
        ["env", {
            "targets": { //指定要轉譯到哪個環境
                //瀏覽器環境
                "browsers": ["last 2 versions", "safari >= 7"],
                //node環境
                "node": "6.10", //"current"  使用當前版本的node
                
            },
             //是否將ES6的模組化語法轉譯成其他型別
             //引數:"amd" | "umd" | "systemjs" | "commonjs" | false,預設為`commonjs`
            "modules": `commonjs`,
            //是否進行debug操作,會在控制檯列印出所有外掛中的log,已經外掛的版本
            "debug": false,
            //強制開啟某些模組,預設為[]
            "include": ["transform-es2015-arrow-functions"],
            //禁用某些模組,預設為[]
            "exclude": ["transform-es2015-for-of"],
            //是否自動引入polyfill,開啟此選項必須保證已經安裝了babel-polyfill
            //引數:Boolean,預設為false.
            "useBuiltIns": false
        }]
    ]
}
{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": [
    "transform-vue-jsx",
    "transform-runtime",
    "syntax-dynamic-import",
    "transform-es2015-modules-commonjs"
  ]
}

plugins

此段內容來自於babel到底該如何配置?

  • babel中的外掛,通過配置不同的外掛才能告訴babel,我們的程式碼中有哪些是需要轉譯的。
  • 外掛官網
{
    "plugins": [
        ["transform-es2015-arrow-functions", { "spec": true }]
    ]
}
  • transform-runtime,這個外掛能自動為專案引入polyfillhelpers
  • polyfill作用是用已經存在的語法和api實現一些瀏覽器還沒有實現的api,對瀏覽器的一些缺陷做一些修補。例如Array新增了includes方法,但是低版本的瀏覽器上沒有,就得做相容處理
  • transform-runtime這個外掛依賴於babel-runtime

babel-runtime由三個部分組成:

core-js
core-js極其強悍,通過ES3實現了大部分的ES5、6、7的polyfill。
regenerator
regenerator來自facebook的一個庫,用於實現 generator functions。
helpers
babel的一些工具函式,這個helpers和使用babel-external-helpers生成的helpers是同一個東西

  • 配置transform-runtime
{
    "plugins": [
        ["transform-runtime", {
            "helpers": false, //自動引入helpers
            "polyfill": false, //自動引入polyfill(core-js提供的polyfill)
            "regenerator": true, //自動引入regenerator
        }]
    ]
}

比較transform-runtime與babel-polyfill引入墊片的差異:

使用runtime是按需引入,需要用到哪些polyfill,runtime就自動幫你引入哪些,不需要再手動一個個的去配置plugins,只是引入的polyfill不是全域性性的,有些侷限性。而且runtime引入的polyfill不會改寫一些例項方法,比如Object和Array原型鏈上的方法,像前面提到的Array.protype.includes。
babel-polyfill就能解決runtime的那些問題,它的墊片是全域性的,而且全能,基本上ES6中要用到的polyfill在babel-polyfill中都有,它提供了一個完整的ES6+的環境。babel官方建議只要不在意babel-polyfill的體積,最好進行全域性引入,因為這是最穩妥的方式。
一般的建議是開發一些框架或者庫的時候使用不會汙染全域性作用域的babel-runtime,而開發web應用的時候可以全域性引入babel-polyfill避免一些不必要的錯誤,而且大型web應用中全域性引入babel-polyfill可能還會減少你打包後的檔案體積(相比起各個模組引入重複的polyfill來說)。

結合ESLint

  • 許多工具需要Babel進行前置轉碼,如ESLint和Mocha
  • 在專案根目錄下,新建一個配置檔案.eslint,在其中加入parser欄位。
{
  "parser": "babel-eslint",
  "rules": {
    ...
  }
}
  • 在package.json之中,加入相應的scripts指令碼
"scripts": {
  "lint": "eslint --ext .js,.vue src",
},

部分參考:
babel到底該如何配置?

相關文章