前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入 Babel 6 loose 模式

深入 Babel 6 loose 模式

作者头像
逆葵
发布2019-04-25 11:16:50
3.8K0
发布2019-04-25 11:16:50
举报
文章被收录于专栏:FECodingFECoding

1.前言

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

在这之前,我们先简单了解一下 Babel 中的一些基础知识:

  • 配置文件 Babel 的配置文件是.babelrc,存放在下项目的根目录下,该文件用来设置预设和插件,基本格式如下: { "presets":[], "plugins":[] }
  • presets(预设) 为了将 Babel 的输出配置为符合要求的情况,我们需要指定 Babel 使用什么插件。可以指定的有:
    • 单独的插件
    • 预设,即支持各种编译方案的插件集合。

    下面是一些使用广泛的预设:

    • es2015:将 ES6 代码编译为 ES5
    • stage-3:将stage 3 ECMAScript proposals编译为ES5
    • react:将 JSX 编译为 JavaScript 并且移除 Flow 的类型注解

    预设通过 npm 安装。他们在 npm 中的包名称为其名字加上前缀babel-preset-。比如安装es2015时,我们可以用以下的命令: npm install babel-preset-es2015

  • plugins(插件) 笼统地讲,插件是在编译过程中应用到输入中的函数。插件有两种重要的类别:
    • 语法插件。其作用为使 Babel 具备处理内建基础语法之外的语法实体。它们能够帮助构造抽象语法树(AST)。典型的语法插件有:syntax-async-functions 以及 syntax-jsx
    • 转换插件。其作用为修改抽象语法树。典型的转换插件有:transform-async-to-generatortransform-react-jsxtransform-es2015-arrow-functions 等。 如果你想编译不包含在基础语法之内的代码,那你将同时需要一个语法插件以及与之相对应的转换插件。不过,每个依赖于语法插件的转换插件都将自动触发该语法插件。 插件同样通过 npm 安装,他们在 npm 中的包名称为其名字加上前缀babel-plugin-
      • 安装插件syntax-jsxnpm install babel-plugin-syntax-jsx
      • 安装插件transform-react-jsxnpm install babel-plugin-transform-react-jsx

OK,基础知识介绍到这里,如想进一步学习 Babel,可以去到Babel官网。下面回归主题,探究 Babel 6 的 loose 模式。

2. 两种模式

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

• 尽可能符合 ECMAScript6 语义的 normal 模式。

• 提供更简单 ES5 代码的 loose 模式。

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

• 优点:生成的代码可能更快,对老的引擎有更好的兼容性,代码通常更简洁,更加的“ES5化”。

• 缺点:你是在冒险——随后从转译的 ES6 到原生的 ES6 时你会遇到问题。这个险是很不值得冒的。

2.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",
   ···
 ],
 ···

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

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

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    toString() {
        return `(${this.x}, ${this.y})`;
    }
}
3.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;
    })();
3.2 loose 模式

在 loose 模式下,用通常的赋值方式添加方法(第 B 行),这种风格更像你用 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() {   // (B)
            return "(" + this.x + ", " + this.y + ")";
        };

        return Point;
    })();

参考文献:

wd4blue-Babel 6: loose 模式 2ality-Configuring Babel

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.前言
  • 2. 两种模式
    • 2.1 切换到 loose 模式
    • 3. 例子:normal 模式与 loose 模式的输出
      • 3.1 normal 模式
        • 3.2 loose 模式
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档