乐趣区

关于babel-preset-env:构建工具babelpresetenv与stagex的使用指南

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

参考地址

  • babel-preset-env
  • babel-preset-env 使用指南
  • browserslist 库
  • 如何辨别 Babel 中的 stage-0,stage-1,stage- 2 以及 stage-3(一)
退出移动版