w3ctech

Babel 6: loose模式

Babel 6: loose 模式

Babel的loose模式将ES6代码转译成ES5代码,loose 模式是不太忠实于ES6语义的。这篇博客解释了它是怎么工作的以及它的优点与缺点(剧透:通常是不推荐的)。

Babel6系列文章的起点:”配置Babel6”[解释基础知识:配置文件、presets、插件,等]

1. 两种模式

许多Babel的插件有两种模式:

• 尽可能符合ECMAScript6语义的normal模式。
• 提供更简单ES5代码的loose模式。

通常,推荐不使用loose模式,使用这种模式的优点和缺点是:

• 优点:生成的代码可能更快,对老的引擎有更好的兼容性,代码通常更简洁,更加的“ES5化”。
• 缺点:你是在冒险——随后从转译的ES6到原生的ES6时你会遇到问题。这个险是很不值得冒的。

1.1 切换到loose模式

es2015-loose是标准的ES6 预设(preset)es2015的loose版。这个预设的代码对什么样的插件有loose模式以及怎样开启提供了很好的说明。以下是代码截选:

module.exports = {
    plugins: [
      ···
      [require("babel-plugin-transform-es2015-classes"), {loose: true}],
      require("babel-plugin-transform-es2015-object-super"),
      ···
    ]
};

这是一个CommonJS模块,可以使用任何的ECMAScript 5,如果你通过.babelrc 或者package.json配置babel(详细配置),你需要使用JSON。也可以包含preset:

···
  "presets": [
    ···
    "es2015-loose",
    ···
  ],
 ···

也可以单独引入插件:

 ···
 "plugins": [
   ···
   ["transform-es2015-classes", {loose: true}],
   "transform-es2015-object-super",
   ···
 ],
 ···

2. 例子:normal模式与loose模式的输出

让我们看看模式如何影响下面代码的编译:

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    toString() {
        return `(${this.x}, ${this.y})`;
    }
}

2.1 normal模式

在normal模式下,类的prototype 方法是通过Object.defineProperty 添加的(第A行),来确保它们是不可以被枚举的,这是ES6规范所要求的。

   "use strict";

    var _createClass = (function () {
        function defineProperties(target, props) {
            for (var i = 0; i < props.length; i++) {
                var descriptor = props[i];
                descriptor.enumerable = descriptor.enumerable || false;
                descriptor.configurable = true;
                if ("value" in descriptor) descriptor.writable = true;
                Object.defineProperty(target, descriptor.key, descriptor); // (A)
            }
        }
        return function (Constructor, protoProps, staticProps) {
            if (protoProps) defineProperties(Constructor.prototype, protoProps);
            if (staticProps) defineProperties(Constructor, staticProps);
            return Constructor;
        };
    })();

    function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
            throw new TypeError("Cannot call a class as a function");
        }
    }

    var Point = (function () {
        function Point(x, y) {
            _classCallCheck(this, Point);

            this.x = x;
            this.y = y;
        }

        _createClass(Point, [{
            key: "toString",
            value: function toString() {
                return "(" + this.x + ", " + this.y + ")";
            }
        }]);

        return Point;
    })();

2.2 loose 模式

在loose模式下,用通常的赋值方式添加方法(第A行),这种风格更像你用ES5手动编写代码。

     "use strict";

    function _classCallCheck(instance, Constructor) { ··· }

    var Point = (function () {
        function Point(x, y) {
            _classCallCheck(this, Point);

            this.x = x;
            this.y = y;
        }

        Point.prototype.toString = function toString() { // (A)
            return "(" + this.x + ", " + this.y + ")";
        };

        return Point;
    })();
w3ctech微信

扫码关注w3ctech微信公众号

共收到0条回复