如何将Babel运行时包含到转换后的代码中?

时间:2017-04-19 04:22:55

标签: javascript node.js ecmascript-6 babeljs

我有一个ES6文件:

function* children(element) {
   for (let i = 0; i < element.children.length; ++i) {
       yield element.children[i];
   }
}

for (const child of children(document.body)) {
    console.log(child);
}

我使用Babel通过JavaScript API将其转换为ES5:

const babel = require('babel-core');
const babelPresetES2015 = require('babel-preset-es2015');
const babelPresetES2016 = require('babel-preset-es2016');
const babelPresetES2017 = require('babel-preset-es2017');

const es6code = '...'; // Actual code fetch is skipped to make the example short

const es5code = babel.transform(es6code, {
    presets: [babelPresetES2015, babelPresetES2016, babelPresetES2017]
}).code;

转换后我得到这段代码:

"use strict";

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

function children(element) {
    var i;
    return regeneratorRuntime.wrap(function children$(_context) {
        while (1) {
            switch (_context.prev = _context.next) {
                case 0:
                    i = 0;

                case 1:
                    if (!(i < element.children.length)) {
                        _context.next = 7;
                        break;
                    }

                    _context.next = 4;
                    return element.children[i];

                case 4:
                    ++i;
                    _context.next = 1;
                    break;

                case 7:
                case "end":
                    return _context.stop();
            }
        }
    }, _marked[0], this);
}

var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;

try {
    for (var _iterator = children(document.body)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
        var child = _step.value;

        console.log(child);
    }
} catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
} finally {
    try {
        if (!_iteratorNormalCompletion && _iterator.return) {
            _iterator.return();
        }
    } finally {
        if (_didIteratorError) {
            throw _iteratorError;
        }
    }
}

问题在于,转换后的代码是指既不在代码中也不在浏览器环境中定义的变量:regeneratorRuntimeSymbol。因此,它无法在浏览器中使用。

如何使用Babel将ES6代码转换为ES5,以便声明所有必需的变量,不会声明多余的变量(不会使代码膨胀)并且代码已准备好在浏览器中工作?

或者至少如何使Babel添加的所有依赖项都在require函数的结果代码中列出?

1 个答案:

答案 0 :(得分:0)

使用Babel transform-runtime插件。它使Babel生成require()的Babel助手(包括regeneratorRuntime)而不是将其添加到代码中的代码。

// ...
const babelPluginTransformRuntime = require('babel-plugin-transform-runtime');

const es5code = babel.transform(es6code, {
    presets: [babelPresetES2015, babelPresetES2016, babelPresetES2017],
    plugins: [babelPluginTransformRuntime]
}).code;

但是,这样做之后,转换后的代码将不包含Babel帮助程序,因此您需要将这些帮助程序安装为NPM依赖项:

npm install --save babel-runtime

并使用RollupWebpackBrowserify之类的JS捆绑器将代码和帮助程序连接在一起。