Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async functions producing an error "ReferenceError: regeneratorRuntime is not defined" #5085

Closed
just-boris opened this issue Jan 10, 2017 · 19 comments

Comments

@just-boris
Copy link

@just-boris just-boris commented Jan 10, 2017

Input Code

async function test() {}

Babel Configuration (.babelrc, package.json, cli command)

{
  "presets": [
    "latest"
  ]
}

Expected Behavior

I expect that the code will run just fine

Current Behavior

It produces the following code, which throws an error ReferenceError: regeneratorRuntime is not defined

"use strict";

var test = function () {
  var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee() {
    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
          case "end":
            return _context.stop();
        }
      }
    }, _callee, this);
  }));

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

Possible Solution

When I have added transform-runtime plugin it also added a require statement babel-runtime/regenerator and the code was run well. But I believe that babel-preset-latest should work at it is, without additional configuration.

Your Environment

software version
Babel v6.21.1
node v6.9.2
npm v3.10.9
Operating System Ubuntu 16.04
@babel-bot
Copy link
Collaborator

@babel-bot babel-bot commented Jan 10, 2017

Hey @just-boris! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@hzoo
Copy link
Member

@hzoo hzoo commented Jan 10, 2017

But I believe that babel-preset-latest should work at it is, without additional configuration.

Not sure how we would do that. Right now you either need transform-runtime or the polyfill. I dont think we can decide that for you. If we did it by default it would be a separate wrapper tool

@just-boris
Copy link
Author

@just-boris just-boris commented Jan 10, 2017

Does that mean that transform-runtime is necessary step to run async functions? Couldn't find it in documentation, but I will happy to contribute this if you will show where I can do it.

@hzoo
Copy link
Member

@hzoo hzoo commented Jan 10, 2017

No like mentioned you can use the polyfill http://babeljs.io/docs/usage/polyfill. Also you can use async-to-gen plugin which transforms to generators (native)

@boneskull
Copy link
Contributor

@boneskull boneskull commented Feb 5, 2017

@hzoo With use in Node.js, if the module which requires babel-polyfill also contains a top-level async function, loading the module will fail with a ReferenceError, because the function is moved before the call to require('babel-polyfill').

The only workaround I've found is to relocate the code containing the async function into a separate module, and require it after babel-polyfill.

Example gist

@loganfsmyth
Copy link
Member

@loganfsmyth loganfsmyth commented Feb 5, 2017

Yeah generally I recommend

import 'babel-polyfill';
import './app';

to initialize everything.

@boneskull Keep in mind that don't recommend that libraries load babel-polyfill. Better to use transform-runtime for library usecases.

@hzoo
Copy link
Member

@hzoo hzoo commented Jul 21, 2017

going to close ^ is the recommendation, otherwise same as #4169

@andersk
Copy link
Contributor

@andersk andersk commented Nov 10, 2017

Hold on. If I write

import 'babel-polyfill';
async function foo() {}

the function is hoisted before the import, leading to ReferenceError: regeneratorRuntime is not defined. But isn’t the import supposed to be hoisted too (#1057)?

@loganfsmyth
Copy link
Member

@loganfsmyth loganfsmyth commented Nov 10, 2017

Function declarations are hoisted before imports are processed. Generally we recommend doing something like

import "babel-polyfill";
import "./app";

if you need to use async functions in your app root.

@andersk
Copy link
Contributor

@andersk andersk commented Nov 10, 2017

@loganfsmyth I understand that's how it works today. But should it? (Should I open a separate issue for this?)

@andersk
Copy link
Contributor

@andersk andersk commented Nov 10, 2017

I found a different workaround, which is to configure Babel with

{
  "presets": [
    ["env", {
      "modules": false
    }]
  ]
}

and rely on Webpack’s native import support. Webpack correctly hoists the import above Babel’s hoisted function.

Perhaps this is a stronger argument that Babel should also do such hoisting with the default "modules": "commonjs", so that the behavior is the same in both cases.

@loganfsmyth
Copy link
Member

@loganfsmyth loganfsmyth commented Nov 10, 2017

I found a different workaround

That's probably reasonable in this case.

Webpack correctly hoists the import above Babel’s hoisted function.

The interaction here is confusing and has a few cases. That said, either way I agree with you that getting the error your getting, just by declaring the code this way, is poor handling on our part. Changing the behavior of imports in our case would not be the right fix, but there is a fix we could do that we haven't done yet, which we probably should.

@Flaque
Copy link

@Flaque Flaque commented Nov 10, 2017

This might be a dumb question, (I don't think I 100% understand how babel works) but why doesn't adding a stage-3 or lower preset work to fix this issue? Doesn't stage-3 include the async-to-generator plugin?

@andersk
Copy link
Contributor

@andersk andersk commented Nov 10, 2017

@Flaque The async-to-generator and transform-regenerator plugins are already assumed to be in use here, else we wouldn’t be talking about regeneratorRuntime at all. This issue is specifically about (1) Babel writing function translations that depend on regeneratorRuntime without automatically adding the import statement needed to bring it into scope, and (2) even if such an import is written manually, Babel hoisting some of these function translations above the hoisted import translation so that regeneratorRuntime isn’t in scope soon enough. It sounds like you might be looking for a completely different issue if any.

@andersk
Copy link
Contributor

@andersk andersk commented Dec 2, 2017

Reopened as #6956.

@jedwards1211
Copy link
Contributor

@jedwards1211 jedwards1211 commented Feb 1, 2018

@hzoo what does it mean if I'm using transform-runtime and my transpiled code includes

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

var _regenerator2 = _interopRequireDefault(_regenerator);

but also includes this statement with the wrong variable name, producing a type error?

var _marked = /*#__PURE__*/_regeneratorRuntime.mark(getShifts);

This file was not having problems before I made some changes, and another file in the same directory gets transpiled correctly, so something is very screwy:

var _marked2 = /*#__PURE__*/_regenerator2.default.mark(getShiftsCore);
@jedwards1211
Copy link
Contributor

@jedwards1211 jedwards1211 commented Feb 1, 2018

@hzoo I'm pretty sure that that babel 6 has a bug when all one generator does is yield * someOtherGenerator() (a degenerate case which I can work around by just changing to a regular function and return someOtherGenerator(), but still, a bug). It's not clear to me if there's still intent to fix bugs in v6, but if so I can file a separate issue with a repro.

@abbassiddiqi
Copy link

@abbassiddiqi abbassiddiqi commented Feb 5, 2018

Update your .babelrc file according to the following examples, it will work.

If you are using @babel/preset-env package

{
  "presets": [
    [
      "@babel/preset-env", {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}

or if you are using babel-preset-env package

{
  "presets": [
    [
      "env", {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}
mcmire added a commit to mcmire/fakenstocks that referenced this issue Feb 8, 2018
This is necessary to be able to use async/await functions, otherwise we
get this error in the console at runtime:

    ReferenceError: regeneratorRuntime is not defined

See: <babel/babel#5085>
thewtex added a commit to thewtex/vtk-js that referenced this issue Feb 21, 2018
These babel bugs are encountered when used in the Karma tests:

  babel/babel#6956
  babel/babel#5085

Just explicitly return a Promise instead.
@iraklisg
Copy link

@iraklisg iraklisg commented Mar 21, 2018

In my case installing babel-plugin-transform-runtime solved my issues:

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

Then, in .babelrc

{
  "plugins": [
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }]
  ]
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
10 participants