Async/Await with React, Webpack and Babel
ReferenceError: regeneratorRuntime is not defined

If you tried using async
/await
in React, you might encounter this error in the
browser:
ReferenceError: regeneratorRuntime is not defined
Your application has been compiled, expecting regeratorRuntime
to be available to interpret the
async
and await
. But you haven't provided the regenerator.
Below are two simple ways to configure Babel to transpile these commands successfully so that they work in your environment. The examples will show how to do it using Webpack.
At the time of writing/editing, these are the versions I'm using
Babel | 7.5 |
---|---|
Webpack | 3.3.5 |
The good and bad ways
There are two prominent ways to do this. The first is better as it does not pollute the global namespace.
Using plugin-transform-runtime
The
plugin-transform-runtime
plugin sandboxes your code and ensures that helper code is not imported more than once, rather re-using
the same
injected helper code. It also automatically injects Regenerator where generators or
async
/await
are used.
It is better than the second option because, according to the Babel docs:
"If you directly import core-js or @babel/polyfill and the built-ins it provides such as Promise, Set and Map, those will pollute the global scope. While this might be ok for an app or a command line tool, it becomes a problem if your code is a library which you intend to publish for others to use or if you can't exactly control the environment in which your code will run."
All you need to do is install these two packages:
- @babel/plugin-transform-runtime
- @babel/runtime
And modify your Webpack configuration to use the plugin with the babel-loader
.
module.exports = {
...
module: {
rules: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
],
plugins: [
'@babel/transform-runtime'
]
}
...
Using @babel/polyfill
This option requires slightly less change, but as the Babel Polyfill Docs suggest, should be avoided.
"As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions)"
It goes on to say that this polyfill is targetting apps and not libraries, as it adds to the global scope and can cause namespace collisions. If you are aware and accept this, then all you need to do is install:
- @babel/polyfill
And add it to the entrypoint in your Webpack configuration:
module.exports = {
entry: [
'babel-polyfill',
'app.jsx'
],
...
Summary
So in summary there are two easy ways to add support for async
/await
using
Babel, as was demonstrated in the Webpack configurations. Only one of these should be used these days.
Bye bye, have fun
References
Bitcoin

Zap me some sats


This blog post itself is licensed under a Creative Commons Attribution 4.0 International License. However, the code itself may be adapted and used freely.