Parcel: Async functions are always transformed to regenerator runtime

Created on 20 Feb 2018  Β·  37Comments  Β·  Source: parcel-bundler/parcel

πŸ› bug report

πŸŽ› Configuration (.babelrc, package.json, cli command)

Without config just do

yarn init
yarn add parcel-bundler

create index.js:

(async function () { return await 1 })()
parcel index.js

πŸ€” Expected Behavior

Without any babel config I would assume no transformation will be made, just bundling into one file.

😯 Current Behavior

Dist file will contain

_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
...

πŸ’ Possible Solution

πŸ”¦ Context

In specific project async functions are transformed no matter what .babelrc I try. I am trying to migrate from browserify but using

node_modules/.bin/parcel build ./src/client/index.js --out-dir ./public --out-file bundle.js --no-minify

will give me code with async functions transformed, where

node_modules/.bin/browserify ./src/client/index.js -o ./public/bundle.js -t [ babelify ]

will keep async functions unchanged. I would expect these to behave the same in regards to babel transforms.

πŸ’» Code Sample

🌍 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.6.2
| Node | v8.1.4
| npm/Yarn | 1.3.2
| Operating System | Mac

Bug babel

Most helpful comment

Found this solution:

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

Create .babelrc file and add:

{
    "plugins": [
        ["transform-runtime",
        {
            "polyfill": false,
            "regenerator": true
        }]
    ]
}

All 37 comments

Seems like it could be related to https://github.com/parcel-bundler/parcel/issues/509 somehow, but no-cache does not help and I did not have any async transform set up anywhere.

Parcel automatically applies babel-preset-env to some default engines (> 1% marketshare). You can change your app's browser targets by adding a browserslist key to your package.json.

@devongovett Thanks for quick reply. As you say using env preset and specific targets helped. Sorry, this was not clear to me from the documentation and is a bit confusing when having a .babelrc defined. I would still assume that defining .babelrc would override the default transforms, while at the moment it seems it is merging them in some sense.

@aocenas That’s a good point. If you want, feel free to open up an issue in the website repo so it get’s added to the docs πŸ‘

I was getting this error when using async/await:
ReferenceError: regeneratorRuntime is not defined

My solution was adding: import "babel-polyfill";

Leaving this comment for reference.

Here my solution:
npm install --save-dev babel-plugin-transform-runtime
And in .babelrc
{ "plugins": ["transform-runtime"] }

Found this solution:

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

Create .babelrc file and add:

{
    "plugins": [
        ["transform-runtime",
        {
            "polyfill": false,
            "regenerator": true
        }]
    ]
}

@brandiqa that solutions looks like very similar to mine but more complete. That is nice!!

@brandiqa this doesn't seem to work when typescript is involved.

tsconfig.json

{
  "compilerOptions": {
    "jsx": "react",
    "experimentalDecorators": true,
    "lib": ["es2017", "dom"],
    "target": "es2018",
    "baseUrl": ".",
    "paths": {
      "react": ["node_modules/@types/react/index.d.ts"],
      "redux": ["node_modules/redux/index.d.ts"],
      "react-toastify": ["node_modules/react-toastify/index.d.ts"]
    }
  }
}

I get this error:

Building index.tsx...
ui_1          | 🚨  /app/src/index.tsx: Unknown plugin "transform-runtime" specified in "base" at 0, attempted to resolve relative to "/app/src"
ui_1          |     at /app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:180:17
ui_1          |     at Array.map (<anonymous>)
ui_1          |     at Function.normalisePlugins (/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:158:20)
ui_1          |     at OptionManager.mergeOptions (/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:234:36)
ui_1          |     at OptionManager.init (/app/node_modules/babel-core/lib/transformation/file/options/option-manager.js:368:12)
ui_1          |     at File.initOptions (/app/node_modules/babel-core/lib/transformation/file/index.js:212:65)
ui_1          |     at new File (/app/node_modules/babel-core/lib/transformation/file/index.js:135:24)
ui_1          |     at TypeScriptAsset.getParserOptions (/app/node_modules/parcel-bundler/src/assets/JSAsset.js:69:20)
ui_1          |     at <anonymous>
{
  "name": "react-parcel-test",
  "version": "1.0.0",
  "license": "MIT",
  "scripts": {
    "start": "./node_modules/.bin/parcel src/index.html --hmr-port $HMR_PORT -p $PORT",
    "dev": "./node_modules/.bin/ts-node src/dev-server.ts"
  },
  "dependencies": {
    "react": "^16.3.2",
    "react-dom": "^16.3.2",
    "react-state-helpers": "^1.6.6",
    "react-toastify": "^4.0.1"
  },
  "devDependencies": {
    "@types/express": "^4.11.1",
    "@types/http-proxy-middleware": "^0.17.4",
    "@types/node": "^10.0.3",
    "@types/react": "^16.3.13",
    "@types/react-dom": "^16.0.5",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-runtime": "^6.26.0",
    "express": "^4.16.3",
    "http-proxy-middleware": "^0.18.0",
    "parcel-bundler": "^1.7.1",
    "ts-node": "^6.0.2",
    "typescript": "^2.8.3"
  }
}

I had accidentally set the config value to:

"plugins": [
    [
      "transform-object-rest-spread",
      "syntax-dynamic-import",
      "transform-runtime",
      {
        "polyfill": false,
        "regenerator": true
      }
    ]
  ]

Changing it to the following worked for me:

"plugins": [
    "transform-object-rest-spread",
    "syntax-dynamic-import",
    [
      "transform-runtime",
      {
        "polyfill": false,
        "regenerator": true
      }
    ]
  ]

Perhaps the runtime transform should be default?

I run into this all the time with demos - so if you want to just ignore this error and use the browsers built in async/await I use this for a quick fix without having to install any babel plugins:

"browserslist": [
    "last 1 Chrome version"
  ],

Is this supposed to work somehow without babel-polyfill?

I tried all the .babelrc plugin settings to no avail.. babel-polyfill did it, but it's a pretty heavy dependency to make something work that actually works natively in all evergreen browsers now

@thedamon: I didn't want to use babel-polyfill either, but @wesbos's suggestion of using browserslist works well. I added the following to package.json:

  "browserslist": [
    "since 2017-06"
  ],

Just an update to @brandiqa solution for those with a babel version of 7^.
The polyfill option has been removed from the transform-runtime plugin has been removed and is now just the following:
["@babel/plugin-transform-runtime", { "regenerator": true } ]

@gcv.. yeah that would work for a lot of users.. i think i just wish there was a way to use async/await simply and still support IE11.. kinda the point of babel.. but without needing the babel-polyfill on all sites because it's like 300k and that's nuts. currently i can't make it work in Chrome without babel-polyfill and that actually makes no sense because it shouldn't be necessary because it shouldn't have anything to polyfill.

but this applies to babel moreso than parcel so i'll stick a lid on it πŸ˜‹

I was getting this error when using async/await:
ReferenceError: regeneratorRuntime is not defined

My solution was adding: import "babel-polyfill";

Leaving this comment for reference.

I am getting the same error and this solution works for me.

@thedamon Does adding @babel/plugin-transform-runtime work for you? Or does it also bloat the production build?

I love how after one year and a half we still don't have a definitive answer to this question. Every solution here includes adding a bunch of dependencies to your project and stopping doing that when the issue actually ceases or seems to be solved.

Gotta love modern JS tooling. It's 2019 and we are struggling to do a simple HTTP request. On the web. <3

True, true, but let's remember that web development is the process of shoehorning state into a stateless evolution of Gopher, and β€” on the front end β€” forcing a system with dreadful display primitives and brain-damaged programming support to work as a universal application delivery system. The web browser exemplifies worse is better in modern software. It's 2019, and we are struggling because turning this lousy platform into a high-level nice-to-program system with convenient and tasteful abstractions is such a _bloody_ hard problem.

On a more practical note, should we petition the Parcel team to re-open this issue or perhaps open a new one?

This is now about regeneratorRuntime is not defined rather than "why are they always transformer", but anyway.

Related: https://github.com/babel/babel/issues/8829#issuecomment-480706039

@mischnic Thanks for re-opening! Hope we can come to a solution to improve UX for Parcel users everywhere :)

Just want to leave a note and say that my code worked with this fix now. Running Babel core 7.7.5. Here is my .babelrc:

{
    "presets": ["@babel/preset-react"],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            { "regenerator": true }
        ]
    ]
}

Just an update to @brandiqa solution for those with a babel version of 7^.
The polyfill option has been removed from the transform-runtime plugin has been removed and is now just the following:
["@babel/plugin-transform-runtime", { "regenerator": true } ]

Premise: typescript and no babel

I was also getting this error when using async/await:
ReferenceError: regeneratorRuntime is not defined

My solution is to change tsconfig target:

// tsconifg.json
{
  "compilerOptions": {
    "target": "es5",
    ...
  },
  ...
}

For reference

Just want to leave a note and say that my code worked with this fix now. Running Babel core 7.7.5. Here is my .babelrc:

{
    "presets": ["@babel/preset-react"],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            { "regenerator": true }
        ]
    ]
}

Just an update to @brandiqa solution for those with a babel version of 7^.
The polyfill option has been removed from the transform-runtime plugin has been removed and is now just the following:
["@babel/plugin-transform-runtime", { "regenerator": true } ]

This works, but we shouldn't need to do this in 2019.

Just want to leave a note and say that my code worked with this fix now. Running Babel core 7.7.5. Here is my .babelrc:

{
    "presets": ["@babel/preset-react"],
    "plugins": [
        [
            "@babel/plugin-transform-runtime",
            { "regenerator": true }
        ]
    ]
}

Just an update to @brandiqa solution for those with a babel version of 7^.
The polyfill option has been removed from the transform-runtime plugin has been removed and is now just the following:
["@babel/plugin-transform-runtime", { "regenerator": true } ]

This works, but we shouldn't need to do this in 2019.

what other options do we have?

what other options do we have?

All major browsers and Node.js have had async/await support for about two years now.
I have found that setting "browserslist": ["since 2017-06"] in package.json does not turn off the regenerator transform in babel, but e.g. "browserslist": ["Chrome 78"] does.

I have tried every single solution (and many combinations of those) in this whole thread and none seems to work for me (except the ones related to TypeScript, as it's not my case) 😞

I can supply more information if needed, just ask it to me and I'll be able to do so.

@danielfilho Are you using the latest version of @babel/core? I just tried with 7.8.4 and it still works as long as you include the "browserslist": ["Chrome 78"] in your package.json (without it it still breaks).

these are the versions I'm using:

 "devDependencies": {
    "@babel/core": "7.2.0",
    "@babel/preset-env": "^7.4.3",
    "babel-jest": "^24.7.1",
    "jest": "^24.7.1",
    "parcel-bundler": "^1.6.1"
  }

Locally, I was trying to update all dependencies to the latest but the problem was still there. Even cleaning node_modules and npm cache.

I solved this giving up on doing locally and moving the development to codesandbox.io, which is far from ideal. But at least I could move on with the project.

I know how weird it sounds, but I tried everything, and then gave up to this solution. Thanks for asking, @corwin-of-amber.

@danielfilho I am attaching a minimal code example that shows the problem so that you and other users visiting this issue could perhaps use to troubleshoot.

Notice how removing browserslist from package.json causes the error (Can't find variable: regeneratorRuntime).

generator-minimal.zip

Thought I'd throw this in, as this seems like the most "correct" way (serious air quotes here) based on what seems like best practice in Babel and what actually ended up working for me:

Install the plugin transform runtime

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

Add this to your .babelrc file

{
  "plugins": ["@babel/plugin-transform-runtime"]
}

I didn't include the runtime or configure any options. Parcel must do this magic? I'm using a Chromium-based browser so I don't know how this works on older browsers, but it fixed this immediate issue for me. Followed the instructions outlined here:

https://babeljs.io/docs/en/babel-plugin-transform-runtime#with-a-configuration-file-recommended

This may be helpful for those that need to make it work with old browsers (e.g.: with the default (or no) browserslist): https://github.com/parcel-bundler/parcel/issues/1762#issuecomment-628071116

The issue is that the dependency regenerator-runtime/runtime needs to be bundled with the rest of your code to make it work on the browser, and Parcel doesn't do that by default.

Seems like this is not fixed (as the workaround from 11/8/2020 shows?), is it no longer an issue in Parcel 2.0.0?

Great! Thanks for adding this reference for anyone who encounters this error in the future.

Was this page helpful?
0 / 5 - 0 ratings