6

I am trying to use ES2017 async/await syntax with Babel. In package.json, I have

"babel": {
    "plugins": [
      "babel-plugin-transform-async-to-generator"
    ],
    "presets": [
      "es2015"
    ]
  }

//...

"devDependencies": {
    "babel-cli": "^6.14.0",
    "babel-plugin-transform-async-to-generator": "^6.8.0",
    "babel-polyfill": "^6.13.0",
    "babel-preset-es2015": "^6.14.0"
  }

The code I am trying to work with is

src/index.js

require("babel-polyfill");

async function foo() {
  return 10;
}

and my built file is

dist/build.js

"use strict";

var foo = function () {
  var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() {
    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            return _context.abrupt("return", 10);

          case 1:
          case "end":
            return _context.stop();
        }
      }
    }, _callee, this);
  }));

  return function foo() {
    return _ref.apply(this, arguments);
  };
}();

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) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }

require("babel-polyfill");

While running the build.js I get this error ReferenceError: regeneratorRuntime is not defined

However, in the build.js, if I move the require("babel-polyfill"); line to the top, it works. But I can't manually do that every time.

So, how to do I use the async/await syntax with babel?

Jatin
  • 14,112
  • 16
  • 49
  • 78

3 Answers3

7

Since functions defined such as

async function foo() {
    return 10;
}

can be used before they're defined in javascript, Babel is moving it to the top of the file during transpilation.

To work around this, this try adjusting your syntax if possible:

const foo = async function() {
    return 10;
}
Community
  • 1
  • 1
Emmett
  • 14,035
  • 12
  • 56
  • 81
3

I think that the require() call must come before the async function (and since functions are hoisted, and you set them up in the same file, the polyfill is loaded later).

Try to require('babel-polyfill') in an earlier stage in the module system. Something like this:

// A.js
require('babel-polyfill');
const foo = require('./B.js');

foo().then(console.log);

// B.js
async function foo() {
  return 10;
}

module.exports.foo = foo;
Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • 2
    yeah, that makes sense. If I use the `var foo = async function () {}` instead of `async function foo() {} `, it works. Although, it still seems like a bug to me, since both syntax are valid. – Jatin Sep 02 '16 at 07:03
1

A different, and probably better solution would be to modularise your code:

  • add an index.js which only exports the stuff you want to export and includes the polyfill
  • add the real functions to small files that only do one thing
Florian Wendelborn
  • 1,667
  • 1
  • 19
  • 29