资讯专栏INFORMATION COLUMN

Runtime transform/runtime 转化器详解

FrancisSoung / 603人阅读

摘要:并且作为生产版本依赖设置转换器插件一般只用在开发时,而里面的实际垫片的代码在你部署或发布库时是需要放到其中的。转换器所做的是转换成如下添加到这意味着你可以无缝的使用本地内置的方法而不用考虑是来自垫片还是本地。。

Runtime transform 运行时编译es6

入口文件引用作为辅助和内建,自动添加垫片到你的当前代码模块而非全局

这个插件建议放在 library/tool中

注意:
实例方法,例如"foobar".includes("foo")将不能够使用,因为它将修正内置的垫片。

为什么使用它 why

Babel对常用的函数使用非常小的辅助(内置的垫片比较少),例如_extend。默认情况下它将会添加到每个引用的文件。这种重复有时候是非常没必要的。特别是你的应用分散在很多文件中。

这是transform-runtime插件之所以产生的原因:所有的这些辅助(垫片)将会引用babel-runtime来避免编译时重复。runtime将会编译到你的build中。

另一个目的是,这个转换器为你的代码创建了一个沙盒环境。如果你使用babel-polyfill并且把它内置提供promise,set,map这样的对象或功能,他们将会污染全局环境。也许在一个应用中或者命令行工具中没问题,但是如果你的代码是个库,你想发布给其他人使用,因为使用的人可能在各种各样的执行环境中,所以可能导致错误,不能执行。

转换器transformer会将这些内置(垫片)设置别名到core-js中,因此你可以不使用require来无缝的使用(垫片中的对象和方法)。

如何生效和工作,请看技术细节

安装

注意:生产版本(Production) vs 开发版本(development)依赖

在大多数情况下,你需要安装babel-plugin-transform-runtime作为开发版本的依赖(设置--save-dev)。

npm install --save-dev babel-plugin-transform-runtime

并且babel-runtime作为生产版本依赖(设置 --save)

npm install --save babel-runtime

转换器插件一般只用在开发时,而里面的实际垫片(runtime itself)的代码在你部署或发布库时是需要放到其中的。

请看下面的例子

用法 通过.babelrc(推荐)

把下面的代码添加到你的babelrc文件中(这里说的是两种情况):

默认设置选项时的写法

{
  "plugins": ["transform-runtime"]
}

使用自己设置设置

{
  "plugins": [
    ["transform-runtime", {
      "helpers": false,
      "polyfill": false,
      "regenerator": true,
      "moduleName": "babel-runtime"
    }]
  ]
}
通过命令行(CLI)
babel --plugins transform-runtime script.js
通过Node 接口 (Node API)
require("babel-core").transform("code",{
    plugins:["transform-runtime"]
})
选项/设置 辅助(helpers)

默认值是:true

表示是否开启内联的babel helpers(即babel或者环境本来的存在的垫片或者某些对象方法函数)(clasCallCheck,extends,etc)在调用模块名字(moduleName)时将被替换名字。

查看详情

垫片/polyfill

默认值是:`true"

表示是否把内置的东西(Promise,Set,Map,tec)转换成非全局污染垫片。
查看详情

重新生成/regenerator

默认值是:true

是否开启generator函数转换成使用regenerator runtime来避免污染全局域。

查看详情

模块名字/moduleName

默认值:babel-runtime

当调用辅助(内置垫片)设置模块(module)名字/路径.

例子:
json

{
  "moduleName": "flavortown/runtime"
}

javascript

import extends from "flavortown/runtime/helpers/extends";
技术细节/Techincal details

runtime转换器插件主要做了三件事:

当你使用generators/async方法、函数时自动调用babel-runtime/regenerator

当你使用ES6 的Map或者内置的东西时自动调用babel-runtime/core-js

移除内联babel helpers并替换使用babel-runtime/helpers来替换

总的来说一句话,你可以使用内置的一些东西例如Promise,Set,Symbol等,就像使用无缝的使用polyfill,来使用babel 特性,并且无全局污染、极高代码库适用性。

再生器别名 Regenerator aliasing

无论你什么时候使用generator函数或者异步函数(async function).

function* foo(){

}

下面的将被生成:

"use strict";

var _marked = [foo].map(regeneratorRuntime.mark);

function foo() {
  return regeneratorRuntime.wrap(function foo$(_context) {
    while (1) switch (_context.prev = _context.next) {
      case 0:
      case "end":
        return _context.stop();
    }
  }, _marked[0], this);
}

这种是不太理想的。因为你regenerator运行时会污染全局域的。
作为替代你需要runtime转换器来编译成:

"use strict";

var _regenerator = require("babel-runtime/regenerator");

var _regenerator2 = _interopRequireDefault(_regenerator);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var _marked = [foo].map(_regenerator2.default.mark);

function foo() {
  return regeneratorRuntime.wrap(function foo$(_context) {
    while (1) switch (_context.prev = _context.next) {
      case 0:
      case "end":
        return _context.stop();
    }
  }, _marked[0], this);
}

这意味着在使用regenerator时不会污染当前的全局环境。

core-js的别名化/core-js aliasing

有时你想去使用内置的的东西(Promise,Set,Map,etc)。通常情况下你会使用一个全局的垫片。
runtime转换器所做的是转换成如下:

var sym = Symbol();

var promise = new Promise;

console.log(arr[Symbol.iterator]());

添加到

"use strict";

var _getIterator2 = require("babel-runtime/core-js/get-iterator");

var _getIterator3 = _interopRequireDefault(_getIterator2);

var _promise = require("babel-runtime/core-js/promise");

var _promise2 = _interopRequireDefault(_promise);

var _symbol = require("babel-runtime/core-js/symbol");

var _symbol2 = _interopRequireDefault(_symbol);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var sym = (0, _symbol2.default)();

var promise = new _promise2.default();

console.log((0, _getIterator3.default)(arr));

这意味着你可以无缝的使用本地内置的方法而不用考虑是来自垫片还是本地。。
警告,实例方法将不能使用,例如"foobar".includes("foo")

辅助重命名 / Helper aliasing

通常babel会把辅助放在文件的顶部做一些常用任务来避免重复导入。
有时这些辅助的体积有点大并且不需要的没有用的东西也在其中。runtime转换器把所有的辅助转换到一个模块中(按他的意思是说只是把用到的转换到其中)。

如下演示:

class Person {
}

一般的转化成(即不是用runtime):

"use strict";

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

var Person = function Person() {
  _classCallCheck(this, Person);
};

runtime转化器转化成:

"use strict";

var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Person = function Person() {
  (0, _classCallCheck3.default)(this, Person);
};

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82500.html

相关文章

  • babel入门

    摘要:为了方便,团队将一些集合在一起,并称之为。先看一下直观体验源代码配置编译后的代码通过对比可以看出,第二种方案直接从引入,避免自己定义,从而减少代码的体积。 Babel Babel 是一个 JavaScript 编译器,它可以将ES6+语法编译为浏览器支持的ES5语法。要学好babel必须先理解相关的概念,但是你刚起步就去扣这些细节的话,很可能因为babel一些复杂而模糊的概念打击你的信...

    pkwenda 评论0 收藏0
  • webpack的Babel加载器

    摘要:的转译过程分为三个阶段。标准为例,提供了如下的一些的只转译该年份批准的标准,而则代指最新的标准,包括和。未完待续,继续学习继续补充哦参考文献深入理解原理及其使用 Babel Babel的转译过程分为三个阶段: parsing, transforming, generating。babel只是转译新标准引入的语法,比如ES6的箭头函数转译成ES5的函数;而新标准引入的原生对象,部分原生对...

    Ali_ 评论0 收藏0
  • webpack实战

    摘要:和类似的预处理器还有等。的用处非常多,包括给自动加前缀使用下一代语法等,目前越来越多的人开始用它,它很可能会成为预处理器的最终赢家。 webpack实战 查看所有文档页面:全栈开发,获取更多信息。快马加鞭,加班加点,终于把这个文档整理出来了,顺便深入地学习一番,巩固知识,就是太累人,影响睡眠时间和质量。极客就是想要把事情做到极致,开始了就必须到达终点。 原文链接:webpack实战,原...

    cyrils 评论0 收藏0
  • Web前端开发过程踩过的坑以及一些小方法技巧(持续更新)

    摘要:一上浏览器使用不允许事件代理到上选择器以上绑定可能会出现点击失效的情况。对于,如果工具是以下版本,在中加入以下代码以上的版本加入以下代码八开发对于文件的处理问题。解决方法有给元素设置绝对定位即可。元素换成内联元素,如。 一、iOS上浏览器使用jQuery不允许事件代理到document上 $(document).on(click, 选择器, function(){}); 以上绑定可能...

    arashicage 评论0 收藏0
  • Web前端开发过程踩过的坑以及一些小方法技巧(持续更新)

    摘要:一上浏览器使用不允许事件代理到上选择器以上绑定可能会出现点击失效的情况。对于,如果工具是以下版本,在中加入以下代码以上的版本加入以下代码八开发对于文件的处理问题。解决方法有给元素设置绝对定位即可。元素换成内联元素,如。 一、iOS上浏览器使用jQuery不允许事件代理到document上 $(document).on(click, 选择器, function(){}); 以上绑定可能...

    binta 评论0 收藏0

发表评论

0条评论

FrancisSoung

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<