A Babel plugin to inject imports to regenerator-runtime polyfills for generator functions and async/await syntax
npx @tessl/cli install tessl/npm-babel-plugin-polyfill-regenerator@0.6.0babel-plugin-polyfill-regenerator is a Babel plugin that automatically injects imports to regenerator-runtime polyfills for generator functions and async/await syntax when they are not natively supported by target environments. The plugin supports multiple injection methods to accommodate different use cases and bundle size requirements.
npm install --save-dev babel-plugin-polyfill-regeneratorThe plugin is designed to be configured in your Babel configuration rather than imported directly:
{
"plugins": [["polyfill-regenerator", { "method": "usage-global" }]]
}For programmatic usage:
const polyfillRegenerator = require("babel-plugin-polyfill-regenerator");import polyfillRegenerator from "babel-plugin-polyfill-regenerator";Configure the plugin in your Babel configuration:
{
"plugins": [
["polyfill-regenerator", {
"method": "usage-global"
}]
]
}The plugin will automatically detect generator functions and async/await usage in your code and inject the appropriate polyfills based on your target environments.
// Input code (automatically transformed):
async function fetchData() {
const response = await fetch('/api/data');
return response.json();
}
function* generateSequence() {
yield 1;
yield 2;
yield 3;
}
// Plugin automatically injects polyfills when needed for target environmentsThe main export is a Babel plugin created using defineProvider from @babel/helper-define-polyfill-provider.
/**
* Babel plugin that provides regenerator-runtime polyfills
* Built using defineProvider framework from @babel/helper-define-polyfill-provider
*/
declare const polyfillRegenerator: PolyfillPlugin<Options>;
export default polyfillRegenerator;
/**
* Plugin options interface
*/
interface Options {
"#__secret_key__@babel/runtime__compatibility"?: void | {
useBabelRuntime: boolean;
moduleName: string;
};
}
/**
* Polyfill plugin type created by defineProvider
*/
interface PolyfillPlugin<T> {
(api: ProviderApi, options: T): ProviderResult;
}
/**
* Provider API passed to the plugin factory
*/
interface ProviderApi {
debug: (name: string | null) => void;
targets: Targets;
babel: {
targets(): Targets;
};
}
/**
* Result returned by the plugin factory
*/
interface ProviderResult {
name: string;
polyfills: string[];
usageGlobal?: (meta: MetaDescriptor, utils: Utils) => undefined;
usagePure?: (meta: MetaDescriptor, utils: Utils, path: NodePath) => void;
}
/**
* Metadata about detected polyfill usage
*/
interface MetaDescriptor {
kind: "global" | "import" | "property" | "in";
name: string;
}
/**
* Utility functions for injecting imports
*/
interface Utils {
injectGlobalImport(url: string): void;
injectDefaultImport(url: string, hint: string): any;
}
/**
* Babel AST node path
*/
interface NodePath {
replaceWith(node: any): void;
hub: {
file: {
get(key: string): any;
};
};
}
/**
* Browser/environment targets
*/
interface Targets {
[target: string]: string;
}The plugin supports three different polyfill injection strategies:
Injects global regenerator-runtime imports only when generator or async features are detected in the code.
/**
* Injects global regenerator-runtime imports for detected usage
* @param meta - Metadata about detected regenerator usage
* @param utils - Utility functions for injecting imports
* @returns undefined when regenerator usage is detected
*/
usageGlobal(meta: MetaDescriptor, utils: Utils): undefined;Configuration:
{
"plugins": [["polyfill-regenerator", { "method": "usage-global" }]]
}Behavior: Calls utils.injectGlobalImport("regenerator-runtime/runtime.js") when regenerator features are detected. The plugin checks if isRegenerator(meta) returns true, which happens when meta.kind === "global" and meta.name === "regeneratorRuntime".
Provides non-global polyfill imports, suitable for library authors who need to avoid global pollution.
/**
* Injects pure (non-global) regenerator-runtime imports
* @param meta - Metadata about detected regenerator usage
* @param utils - Utility functions for injecting imports
* @param path - Babel AST path for the usage site
*/
usagePure(meta: MetaDescriptor, utils: Utils, path: NodePath): void;Configuration:
{
"plugins": [["polyfill-regenerator", { "method": "usage-pure" }]]
}Behavior: When regenerator features are detected, replaces the usage with pure imports. The implementation:
"regenerator-runtime"useBabelRuntime is enabled, constructs runtime path:
moduleName if providedruntimeHelpersModuleName"@babel/runtime""${runtimeName}/regenerator"path.replaceWith(utils.injectDefaultImport(pureName, "regenerator-runtime"))Replaces imports to regenerator-runtime at entry points.
Configuration:
{
"plugins": [["polyfill-regenerator", { "method": "entry-global" }]]
}Behavior: Handled by the defineProvider framework when method is "entry-global".
The plugin supports integration with @babel/runtime for pure imports:
interface RuntimeCompatibilityOptions {
/** Whether to use @babel/runtime for pure imports, or runtime module name */
useBabelRuntime?: boolean | string;
/** Custom module name for runtime imports (defaults to "@babel/runtime") */
moduleName?: string;
}Usage with @babel/runtime:
{
"plugins": [
["polyfill-regenerator", {
"method": "usage-pure",
"#__secret_key__@babel/runtime__compatibility": {
"useBabelRuntime": "@babel/runtime"
}
}]
]
}Alternative boolean form:
{
"plugins": [
["polyfill-regenerator", {
"method": "usage-pure",
"#__secret_key__@babel/runtime__compatibility": {
"useBabelRuntime": true,
"moduleName": "@babel/runtime"
}
}]
]
}/**
* Internal utility function that checks if a meta descriptor represents regenerator usage
* @param meta - The meta descriptor to check
* @returns true if meta represents regeneratorRuntime global usage
*/
function isRegenerator(meta: MetaDescriptor): boolean;
/**
* Internal utility function for shallow equality comparison
* @param obj1 - First object to compare
* @param obj2 - Second object to compare
* @returns true if objects are shallowly equal
*/
function shallowEqual(obj1: any, obj2: any): boolean;The plugin provides polyfills for the following functionality:
/**
* Array of polyfill names provided by this plugin
*/
const polyfills: ["regenerator-runtime"];Polyfill Coverage:
regenerator-runtime: Polyfills for generator functions (function*) and async/await syntaxSpecifies the polyfill injection strategy:
"usage-global": Inject global polyfills only for detected usage (recommended for applications)"usage-pure": Inject pure polyfills for detected usage (recommended for libraries)"entry-global": Replace regenerator-runtime imports at entry pointsAdvanced option for @babel/runtime integration:
{
"#__secret_key__@babel/runtime__compatibility": {
"useBabelRuntime": true,
"moduleName": "@babel/runtime"
}
}The plugin supports absolute imports when used with compatible build tools:
{
"plugins": [
["polyfill-regenerator", {
"method": "usage-pure",
"absoluteImports": true
}]
]
}The plugin validates configuration and throws descriptive errors:
"This plugin does not use the targets option. Only preset-env's targets or top-level targets need to be configured for this plugin to work. See https://github.com/babel/babel-polyfills/issues/36 for more details."@babel/helper-define-polyfill-provider framework (workspace dependency ^0.6.5)defineProvider function to create the plugin with proper polyfill injection methodsbabel.targets() comparison for validation^7.4.0 || ^8.0.0-0 <8.0.0)lib/index.js) and ESM (esm/index.mjs) output formatsisRegenerator helper function