官方文档上
Runtime transform
Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals
从最终的行为来解释就是说babel引入了helper工具函数自动来执行polyfill并且不污染全局作用于,采用require的方式。
This plugin is recommended in a library/tool.
推荐在工具库中使用。
NOTE: Instance methods such as “foobar”.includes(“foo”) will not work since that would require modification of existing built-ins (Use babel-polyfill for that).
同时该插件并不会转换诸如数组的includes方法
polyfill
This will emulate a full ES2015 environment and is intended to be used in an application rather than a library/tool. This polyfill is automatically loaded when using babel-node
polyfill 本质上就是一个降级方案,它作用在全局,将你的ES6语法做转换。
差异
- 都做转换
- 但是polyfill转换的东西更多更全面
- 而runtime仅仅转换一些语法,类似数组的API是不做转换的
- polyfill作用在全局
- 而runtime则是通过引用模块的方式来实现
- 那些需要修改内置api才能达成的功能,譬如:扩展String.prototype,给上面增加includes方法,就属于修改内置API的范畴,这是polyfill来做的
不使用transform-runtime转换async/await
代码语言:javascript复制"use strict";
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"); }); }; }
_asyncToGenerator(regeneratorRuntime.mark(function _callee() {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return loadStory();
case 2:
console.log("Yey, story successfully loaded!");
case 3:
case "end":
return _context.stop();
}
}
}, _callee, this);
}))();
使用transform-runtime 转换async/await
代码语言:javascript复制"use strict";
var _regenerator = require("babel-runtime/regenerator");
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require("babel-runtime/helpers/asyncToGenerator");
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
(0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee() {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return loadStory();
case 2:
console.log("Yey, story successfully loaded!");
case 3:
case "end":
return _context.stop();
}
}
}, _callee, this);
}))();
这里可以看到两者的区别在于,使用了transform-runtime 之后 babel会自动引入模块的方式来实现es5的写法,可以看出是利用了babel的工具函数,工具函数中把Promise都实现了一遍。
而不用 transform-runtime 的时候,仅仅是使用 Promise 来实现 async/await 但是并未考虑对 Promise 做转换。 总结:
- 具体项目还是需要使用 babel-polyfill,只使用 babel-runtime 的话,实例方法不能正常工作(例如 “foobar”.includes(“foo”))。
- JavaScript 库和工具可以使用 babel-runtime,在实际项目中使用这些库和工具,需要该项目本身提供 polyfill。
- 单独的库如果仅仅是转换ES6语法,那么也可以不使用runtime,babel本身就是会自带这部分的转换的。