babel-preset-env與stage-x的使用指南


babel介紹

babel總共分為3個階段: 解析、轉換和生成

babel本身不具有任何轉換功能, 如果沒有plugin,那么經過babel的代碼和輸入的是相同的。

babel插件分為兩種

  • 語法插件:在解析的過程中,能使babel能夠解析更多的語法
  • 轉譯插件: 在轉換的過程中將代碼輸出。比如將箭頭函數轉譯成正常的函數

其中preset就是babel常用的轉譯插件

preset介紹

preset是一套規范, 里面包含了幾十個轉譯插件。這是一組插件的集合

preset可以分為下面幾種:

  • 1.按官方內容: env, react, flow, minify;
  • 2.stage-x:stage-0 至 stage-3代表了es標准支持的不同階段。0階段是最初級的階段,可以理解為僅僅才開始討論標准, 換句話說就是基本沒有什么瀏覽器支持es新標准。3表示成熟階段,意味着主流瀏覽器的新版本都支持大部分新標准,基礎的es新標准特性不需要降級編譯為es5,瀏覽器即可原生支持。

stage-3包括以下插件:

  • transform-async-to-generator  支持async/await
  • transform-exponentiation-operator 支持冪運算符語法糖

stage-2包括stage-3的所有插件,額外還包括以下插件:

  • syntax-trailing-function-commas 支持尾逗號函數,額...很雞肋
  • transform-object-reset-spread 支持對象的解構賦值

stage-1包括stage2所有插件,額外還包括以下插件:

  • transform-class-constructor-call 支持class的構造函數
  • transform-class-properties 支持class的static屬性
  • transform-decorators  支持es7的裝飾者模式即@符號引入的方法 (還在討論中的特性?)
  • transform-export-extensions 支持export方法

stage-0包括stage1所有插件,額外還包括以下插件:

  • transform-do-expressions 支持在jsx中書寫if/else
  • transform-function-bind 支持::操作符來切換上下文,類似於es5的bind

babel-preset-env

歷史版本babel-preset-latest(已被棄用)

最初,為了讓開發者能夠盡早用上新的JS特性,babel團隊開發了babel-preset-latest。這個preset比較特殊,它是多個preset的集合(es2015+),並且隨着ECMA規范的更新更增加它的內容。

  • 特點:包含了所有年度預設(babel-preset-es2015、babel-preset-es2016、babel-preset-es2017),無需用戶單獨指定某個預設。
  • 缺點:部分轉碼多余,如果使用默認設置,babel會將所有ES6與ES6+的新特性轉成復雜的es5的代碼。但是大部分現在瀏覽器已經支持ES6的部分特性。

因為上述問題的存在,babel官方推出了babel-preset-env插件。它可以根據開發者的配置,按需加載插件。配置項大致包括:

  • 需要支持的平台:比如node、瀏覽器等。
  • 需要支持的平台的版本:比如支持node@6.1等。

默認配置的情況下,它跟babel-preset-latest是等同的,會加載從es2015開始的所有preset。

//默認設置
{
  "presets": ["env"]
}

入門實例

首先,安裝依賴:

npm install babel-cli --save-dev
npm install babel-preset-env --save-dev

創建一個index.js文件:

let foo = () => 'foo';

配置文件 .babelrc 如下,當前為默認配置。

{
  "presets": [ "env" ]
}

對index.js文件執行babel轉化命令:

// 方式一:
.\node_modules\.bin\babel index.js

// 方式二(npm5.2支持):
npx babel index.js

轉換結果如下:

'use strict';

var foo = function foo() {
  return 'foo';
};

針對node版本的配置

babel-preset-env 提供了更精細化的配置,以提升編譯速度,同時減少代碼冗余。 比如我們index.js的代碼如下:

// index.js
async function foo () {}

采用 babel-preset-env,默認配置下,編譯后的代碼如下:

use strict";

var foo = function () {
  var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
          case "end":
            return _context.stop();
        }
      }
    }, _callee, this);
  }));

  return function foo() {
    return _ref.apply(this, arguments);
  };
}();

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

結果很長,無需關心。如果我們的代碼是在node@8.9.3版本上運行,那上面的這些兼容代碼就是冗余的,因為node@8.9.3已經支持了async/await。

修改下 .babelrc,加上配置參數"target",它表示我們需要支持哪些平台+哪些版本。這里聲明我們要支持的是node版本為8.9.3。

{
  "presets": [
    ["env", {
      "targets": {
        "node": "8.9.3"
      }      
    }]
  ]
}

再次進行轉碼,結果如下:

"use strict";

async function foo() {}

針對瀏覽器版本的配置

babel-preset-env 同樣提供了對瀏覽器版本的配置能力。 比如,我們需要支持 IE8+、chrome62+,那么可以這樣配置:

{
  "presets": [
    ["env", {
      "targets": {
        "browsers": [ "ie >= 8", "chrome >= 62" ]
      }      
    }]
  ]
}

看下前面聲明的范圍涵蓋了哪些瀏覽器:

npx browserslist "ie >= 8, chrome >= 62"
chrome 81
chrome 80
chrome 79
chrome 78
chrome 77
chrome 76
chrome 75
chrome 74
chrome 73
chrome 72
chrome 71
chrome 70
chrome 69
chrome 68
chrome 67
chrome 66
chrome 65
chrome 64
chrome 63
chrome 62
ie 11
ie 10
ie 9
ie 8

當然上面的配置規則不是憑空想象,其它的具體配置規則可參考《 browserslist 庫》

stage-x(實驗階段presets)

默認不會包含stage-x插件,需要手動配置支持

"presets": [
    // 帶了配置項,自己變成數組
    [
        // 第一個元素依然是名字
        "env",
        // 第二個元素是對象,列出配置項
        {
          "modules": false //  將ES6模塊語法轉換為另一種模塊類型,"amd" | "umd" | "systemjs" | "commonjs" | false
        }
    ],

    // 不帶配置項,直接列出名字
    "stage-2"
]

根據需求安裝不同版本的stage:

# ES7不同階段語法提案的轉碼規則(共有4個階段),選裝一個
$ npm install --save-dev babel-preset-stage-0
$ npm install --save-dev babel-preset-stage-1
$ npm install --save-dev babel-preset-stage-2
$ npm install --save-dev babel-preset-stage-3

參考地址

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM