A Babel plugin that transforms async functions into module method calls. This plugin enables compatibility with older JavaScript environments and provides integration with different Promise libraries by allowing configuration of the target module and method.
npm install --save-dev babel-plugin-transform-async-to-module-methodThis plugin is imported and used through Babel's configuration system rather than direct module imports:
Via .babelrc:
{
"plugins": [
["transform-async-to-module-method", {
"module": "bluebird",
"method": "coroutine"
}]
]
}Via CLI:
babel --plugins transform-async-to-module-method script.js
# With options
babel --plugins transform-async-to-module-method --plugin-opts '{"module":"bluebird","method":"coroutine"}' script.jsVia Node API:
require("babel-core").transform("code", {
plugins: [
["transform-async-to-module-method", {
module: "bluebird",
method: "coroutine"
}]
]
});Configuration with Bluebird coroutines (typical usage):
Input:
async function fetchUser(id) {
const response = await fetch(`/users/${id}`);
return await response.json();
}Output:
import { coroutine as _coroutine } from "bluebird";
let fetchUser = (() => {
var _ref = _coroutine(function* (id) {
const response = yield fetch(`/users/${id}`);
return yield response.json();
});
return function fetchUser(id) {
return _ref.apply(this, arguments);
};
})();The plugin operates as a Babel transformation plugin with the following key components:
babel-helper-remap-async-to-generator for the actual transformationMain plugin factory function that returns Babel plugin configuration.
/**
* Default export function that creates a Babel plugin
* @param {object} babel - Babel API object
* @returns {BabelPlugin} Babel plugin configuration object
*/
export default function(babel): BabelPlugin;
interface BabelPlugin {
inherits: any; // babel-plugin-syntax-async-functions
visitor: {
Function(path: NodePath, state: PluginState): void;
};
}The plugin accepts configuration options to customize the transformation target:
interface PluginOptions {
/** Name of the module to import (defaults to "bluebird") */
module?: string;
/** Name of the method to call (defaults to "coroutine") */
method?: string;
}Configuration Examples:
With Bluebird coroutines (typical usage):
{
"plugins": [
["transform-async-to-module-method", {
"module": "bluebird",
"method": "coroutine"
}]
]
}With default options (equivalent to above):
{
"plugins": ["transform-async-to-module-method"]
}With custom module and method:
{
"plugins": [
["transform-async-to-module-method", {
"module": "co",
"method": "wrap"
}]
]
}The plugin's visitor method that processes Function AST nodes:
/**
* Visitor method for Function AST nodes
* @param {NodePath} path - Babel AST path object for the function
* @param {PluginState} state - Plugin state containing options and file context
*/
Function(path: NodePath, state: PluginState): void;
interface PluginState {
opts: PluginOptions;
file: {
addImport(module: string, method: string): any;
};
}The plugin transforms async functions using the following logic:
babel-helper-remap-async-to-generator to convert async/await to generator/yieldSupported Function Types:
async function foo() {}const foo = async function() {}const foo = async () => {}class C { async method() {} }Excluded Functions:
async function* gen() {} (skipped)interface NodePath {
node: {
async: boolean;
generator: boolean;
};
}
interface BabelPlugin {
inherits: any;
visitor: {
[key: string]: (path: NodePath, state: PluginState) => void;
};
}
interface PluginOptions {
module: string;
method: string;
}
interface PluginState {
opts: PluginOptions;
file: {
addImport(module: string, method: string): any;
};
}Custom Promise Library Integration:
{
"plugins": [
["transform-async-to-module-method", {
"module": "when/generator",
"method": "lift"
}]
]
}Multiple Async Functions:
Input:
async function fetchData() {
return await api.getData();
}
const processData = async (data) => {
const result = await transform(data);
return result;
};
class DataHandler {
async save(data) {
await this.validate(data);
return await this.store(data);
}
}Output with class methods:
import { coroutine as _coroutine } from "bluebird";
let fetchData = (() => {
var _ref = _coroutine(function* () {
return yield api.getData();
});
return function fetchData() {
return _ref.apply(this, arguments);
};
})();
const processData = (() => {
var _ref = _coroutine(function* (data) {
const result = yield transform(data);
return result;
});
return function processData(data) {
return _ref.apply(this, arguments);
};
})();
class DataHandler {
save(data) {
return _coroutine(function* () {
yield this.validate(data);
return yield this.store(data);
}.bind(this))();
}
}All async functions are transformed to use the configured module method while preserving their original signatures and behavior.