Babel plugin that transforms async functions and generators into state machines using regenerator runtime.
npx @tessl/cli install tessl/npm-babel-plugin-transform-regenerator@6.26.0babel-plugin-transform-regenerator transforms async functions and generator functions into state machines using Facebook's regenerator library. It enables support for ES6 generators and ES2017 async/await syntax by converting them to ES5-compatible code that works with the regenerator runtime.
npm install --save-dev babel-plugin-transform-regeneratorFor Babel configuration files:
{
"plugins": ["transform-regenerator"]
}For Node.js API usage:
const babel = require("babel-core");{
"plugins": ["transform-regenerator"]
}{
"plugins": [
["transform-regenerator", {
"asyncGenerators": true,
"generators": true,
"async": true
}]
]
}babel --plugins transform-regenerator script.jsconst babel = require("babel-core");
const result = babel.transform(code, {
plugins: ["transform-regenerator"]
});babel-plugin-transform-regenerator is designed as a lightweight wrapper around Facebook's regenerator-transform library. The plugin follows Babel's standard plugin architecture:
src/index.js) re-exports the regenerator-transform package, providing seamless integration with Babel's plugin systemThis architecture separates the Babel integration layer from the transformation logic, allowing the plugin to leverage the mature regenerator-transform library while maintaining compatibility with Babel's ecosystem.
The main plugin export that provides Babel transformation functionality for async functions and generators.
/**
* Babel plugin function that transforms async and generator functions
* Exported from regenerator-transform package
* @returns {BabelPlugin} Babel plugin object with visitor methods
*/
module.exports = require("regenerator-transform");The plugin accepts configuration options to control which types of functions are transformed.
/**
* Plugin configuration options
* @typedef {Object} RegeneratorOptions
* @property {boolean} [asyncGenerators=true] - Enable transformation of async generator functions
* @property {boolean} [generators=true] - Enable transformation of generator functions
* @property {boolean} [async=true] - Enable transformation of async functions
*/Usage with Options:
// Via .babelrc
{
"plugins": [
["transform-regenerator", {
"asyncGenerators": false, // Disable async generator transformation
"generators": true, // Keep generator transformation enabled
"async": true // Keep async function transformation enabled
}]
]
}
// Via Node API
babel.transform(code, {
plugins: [
["transform-regenerator", {
asyncGenerators: true,
generators: true,
async: true
}]
]
});Input:
function* generator() {
yield 1;
yield 2;
return 3;
}Output:
var _marked = [generator].map(regeneratorRuntime.mark);
function generator() {
return regeneratorRuntime.wrap(function generator$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return 1;
case 2:
_context.next = 4;
return 2;
case 4:
return _context.abrupt("return", 3);
case 5:
case "end":
return _context.stop();
}
}
}, _marked[0], this);
}Input:
async function fetchData() {
const response = await fetch('/api/data');
return response.json();
}Output:
function fetchData() {
return regeneratorRuntime.async(function fetchData$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return regeneratorRuntime.awrap(fetch('/api/data'));
case 2:
response = _context.sent;
return _context.abrupt("return", response.json());
case 4:
case "end":
return _context.stop();
}
}
}, null, this);
}Input:
async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
}Output:
var _marked = [asyncGenerator].map(regeneratorRuntime.mark);
function asyncGenerator() {
return regeneratorRuntime.wrap(function asyncGenerator$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return regeneratorRuntime.awrap(Promise.resolve(1));
case 2:
_context.next = 4;
return _context.sent;
case 4:
_context.next = 6;
return regeneratorRuntime.awrap(Promise.resolve(2));
case 6:
_context.next = 8;
return _context.sent;
case 8:
case "end":
return _context.stop();
}
}
}, _marked[0], this);
}The transformed code requires the regeneratorRuntime to be available in the execution environment. This can be provided by:
// If using babel-runtime
import "babel-runtime/regenerator";
// If using babel-polyfill
import "babel-polyfill";
// If using standalone regenerator-runtime
import "regenerator-runtime/runtime";module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: ['transform-regenerator']
}
}
}
]
}
};import babel from 'rollup-plugin-babel';
export default {
plugins: [
babel({
plugins: ['transform-regenerator']
})
]
};When you only need specific transformation types:
{
"plugins": [
["transform-regenerator", {
"asyncGenerators": false,
"generators": true,
"async": false
}]
]
}This configuration will only transform generator functions, leaving async functions and async generators untransformed.