A Babel plugin that transforms async and generator functions into regenerator-runtime-based state machines, enabling modern JavaScript async/await and generator syntax to work in environments that don't natively support these features.
npm install --save-dev @babel/plugin-transform-regenerator// ES Module
import transformRegeneratorPlugin from "@babel/plugin-transform-regenerator";
// CommonJS
const transformRegeneratorPlugin = require("@babel/plugin-transform-regenerator").default;{
"plugins": ["@babel/plugin-transform-regenerator"]
}With options:
{
"plugins": [
["@babel/plugin-transform-regenerator", {
"async": true,
"generators": true,
"asyncGenerators": true
}]
]
}import babel from "@babel/core";
import transformRegeneratorPlugin from "@babel/plugin-transform-regenerator";
const result = babel.transform(code, {
plugins: [transformRegeneratorPlugin]
});The main plugin export that provides async and generator function transformation. The plugin is created using @babel/helper-plugin-utils's declare function.
/**
* Babel plugin that transforms async and generator functions into state machines
* Created using @babel/helper-plugin-utils declare() with visitor pattern
*/
function transformRegeneratorPlugin(): BabelPluginObj;
export default transformRegeneratorPlugin;
interface BabelPluginObj {
name: "transform-regenerator";
visitor: {
Method(path: NodePath, state: PluginPass): void;
Function: {
exit(path: NodePath, state: PluginPass): void;
};
};
}
interface PluginPass {
opts: PluginOptions;
addHelper(name: string): t.Expression;
availableHelper?(name: string): boolean;
}Configure which types of functions to transform.
interface PluginOptions {
/** Enable/disable transformation of async functions (default: true) */
async?: boolean;
/** Enable/disable transformation of generator functions (default: true) */
generators?: boolean;
/** Enable/disable transformation of async generator functions (default: true) */
asyncGenerators?: boolean;
}Usage Examples:
// Transform only async functions
{
"plugins": [
["@babel/plugin-transform-regenerator", {
"async": true,
"generators": false,
"asyncGenerators": false
}]
]
}
// Transform only generators
{
"plugins": [
["@babel/plugin-transform-regenerator", {
"async": false,
"generators": true,
"asyncGenerators": false
}]
]
}
// Default: transform all types
{
"plugins": ["@babel/plugin-transform-regenerator"]
}The plugin performs the following transformations:
Transforms async functions into regenerator-runtime state machines with Promise handling:
// Input
async function fetchData() {
const response = await fetch('/api/data');
return response.json();
}
// Output (with modern helpers)
function fetchData() {
return babelHelpers.regeneratorAsync(function fetchData$(_context) {
while (1) {
switch (_context.n) {
case 0:
_context.n = 1;
return babelHelpers.awaitAsyncGenerator(fetch('/api/data'));
case 1:
response = _context.v;
return _context.a(2, response.json());
case 2:
case "end":
return _context.stop();
}
}
}, null, null, null, Promise);
}Transforms generator functions into regenerator-runtime state machines with iterator protocol:
// Input
function* numbers() {
yield 1;
yield 2;
yield 3;
}
// Output (with modern helpers)
var _marked = /*#__PURE__*/babelHelpers.regenerator().m(numbers);
function numbers() {
return babelHelpers.regenerator().w(function numbers$(_context) {
while (1) {
switch (_context.n) {
case 0:
_context.n = 1;
return 1;
case 1:
_context.n = 2;
return 2;
case 2:
_context.n = 3;
return 3;
case 3:
case "end":
return _context.stop();
}
}
}, _marked);
}Combines both async and generator transformation patterns:
// Input
async function* asyncNumbers() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
}
// Output (with modern helpers)
function asyncNumbers() {
return babelHelpers.regeneratorAsyncGen(function asyncNumbers$(_context) {
while (1) {
switch (_context.n) {
case 0:
_context.n = 1;
return babelHelpers.awaitAsyncGenerator(Promise.resolve(1));
case 1:
_context.n = 2;
return _context.v;
case 2:
_context.n = 3;
return babelHelpers.awaitAsyncGenerator(Promise.resolve(2));
case 3:
_context.n = 4;
return _context.v;
case 4:
case "end":
return _context.stop();
}
}
}, null, null, null, Promise);
}workspace:^ - Provides the declare function for plugin creation^7.0.0-0 - Required for plugin operation and AST manipulationThe plugin uses different helper functions depending on the Babel version:
Modern Babel (@babel/helpers >= 7.18.0):
regenerator() - Main regenerator helper that provides .m(), .w(), .a() methodsregeneratorAsync - For async function transformationsregeneratorAsyncGen - For async generator function transformationsawaitAsyncGenerator - For await expression transformationsLegacy Babel:
regeneratorRuntime - Global runtime with .mark(), .wrap(), .async(), .awrap() methodsThe transformed code requires regenerator-runtime to be available at runtime. This can be provided through:
@babel/polyfill (deprecated)@babel/runtime with @babel/plugin-transform-runtimeregenerator-runtime package@babel/preset-env with appropriate polyfill configuration// Manual runtime inclusion
import "regenerator-runtime/runtime";
// Or with @babel/plugin-transform-runtime
{
"plugins": [
"@babel/plugin-transform-regenerator",
["@babel/plugin-transform-runtime", {
"regenerator": true
}]
]
}
// Or using babel-plugin-polyfill-regenerator
{
"plugins": [
"@babel/plugin-transform-regenerator",
["babel-plugin-polyfill-regenerator", {
"method": "usage-global"
}]
]
}The plugin's output varies based on the Babel version and helper availability:
Babel 8 (BABEL_8_BREAKING mode):
regenerator(), regeneratorAsync, regeneratorAsyncGen.m(), .w(), .a(), .n, .vBabel 7 (Legacy mode):
regeneratorRuntime global object.mark(), .wrap(), .async(), .awrap()This plugin is commonly used with:
function.sent meta-property in generatorsThe plugin handles various edge cases during transformation:
this context in transformed functionsarguments object references in transformed functionsCommon transformation errors are related to:
This plugin enables async/generator support in:
The generated code is ES5-compatible when regenerator-runtime is available.