Babel plugin that transforms ES2015 modules to Asynchronous Module Definition (AMD) format
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Babel plugin that transforms ES2015 (ES6) module syntax into Asynchronous Module Definition (AMD) format. It converts ES6 import/export statements into AMD's define() function calls, enabling ES6 modules to work in AMD-compatible environments like RequireJS.
npm install --save-dev babel-plugin-transform-es2015-modules-amd// Via require()
const plugin = require("babel-plugin-transform-es2015-modules-amd");
// ES module import (for plugin development)
import plugin from "babel-plugin-transform-es2015-modules-amd";{
"plugins": ["transform-es2015-modules-amd"]
}babel --plugins transform-es2015-modules-amd script.jsrequire("babel-core").transform("code", {
plugins: ["transform-es2015-modules-amd"]
});Input:
export default 42;Output:
define(["exports"], function (exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = 42;
});The main export is a plugin factory function that creates a Babel plugin.
/**
* Creates a Babel plugin for transforming ES2015 modules to AMD format
* @param {Object} babel - Babel object containing types and utilities
* @param {Object} babel.types - Babel types for AST manipulation
* @returns {Object} Babel plugin configuration object
*/
function default({ types: t }) {
return {
inherits: require("babel-plugin-transform-es2015-modules-commonjs"),
pre: function() { /* initialization */ },
visitor: {
Program: {
exit: function(path) { /* transformation logic */ }
}
}
};
}The plugin inherits configuration options from babel-plugin-transform-es2015-modules-commonjs:
interface PluginOptions {
/** Controls handling of top-level 'this' expressions */
allowTopLevelThis?: boolean;
/** Uses loose mode for __esModule property definition */
loose?: boolean;
/** Prevents __esModule property from being exported */
strict?: boolean;
/** Disables automatic interop helper usage */
noInterop?: boolean;
/** Enables module ID generation for AMD modules */
moduleIds?: boolean;
/** Custom module ID for the transformed module */
moduleId?: string;
}Option Details:
allowTopLevelThis (boolean, default: false): When true, preserves top-level this expressions; when false, replaces them with undefinedloose (boolean, default: false): When true, uses simple assignment exports.__esModule = true; when false, uses Object.definePropertystrict (boolean, default: false): When true, prevents the __esModule property from being exportednoInterop (boolean, default: false): When true, avoids interop helpers and uses direct member accessmoduleIds (boolean, default: false): When true, enables automatic module ID generationmoduleId (string, default: undefined): Specifies a custom module ID for the AMD moduleThe returned plugin object contains the following properties:
interface BabelPlugin {
/** Inherits functionality from the CommonJS modules plugin */
inherits: any;
/** Pre-transformation initialization function */
pre(): void;
/** AST visitor configuration */
visitor: {
Program: {
exit(path: any): void;
};
};
}While not part of the public API, these internal functions and constants demonstrate the plugin's capabilities:
/**
* Template for creating AMD define() function wrapper
*/
const buildDefine: TemplateFunction;
/**
* Template for creating AMD factory function
*/
const buildFactory: TemplateFunction;
/**
* Validates if a call expression is a valid require() call
* @param {Object} path - Babel AST path
* @returns {boolean} True if valid require() call
*/
function isValidRequireCall(path: any): boolean;
/**
* Gets module name for AMD module (inherited from CommonJS plugin)
* @returns {string|undefined} Module name if configured
*/
this.getModuleName(): string | undefined;The plugin transforms various ES6 module patterns:
Named Imports:
// Input
import { foo } from "module";
// Output (within define wrapper)
define(["module"], function (_module) {
// foo is accessed as _module.foo
});Default Imports:
// Input
import foo from "module";
// Output (within define wrapper)
define(["module"], function (_module) {
var foo = _module.default;
});Namespace Imports:
// Input
import * as foo from "module";
// Output (within define wrapper)
define(["module"], function (foo) {
// foo contains entire module
});Mixed Imports:
// Input
import foo, { bar } from "module";
// Output (within define wrapper)
define(["module"], function (_module) {
var foo = _module.default;
// bar accessed as _module.bar
});Default Export:
// Input
export default value;
// Output (within define wrapper)
define(["exports"], function (exports) {
exports.default = value;
});Named Exports:
// Input
export { foo, bar };
// Output (within define wrapper)
define(["exports"], function (exports) {
exports.foo = foo;
exports.bar = bar;
});All transformed modules follow this structure:
define([dependencies], function (dependencyParams) {
"use strict";
// Module body with transformed imports/exports
// Original ES6 code converted to CommonJS-style
return exports; // or module.exports equivalent
});The plugin handles various edge cases:
require("string") patternsmodule, exports, and require identifiers// .babelrc
{
"plugins": [
["transform-es2015-modules-amd", {
"moduleIds": true,
"moduleId": "my-custom-module"
}]
]
}
// Output includes module ID
define("my-custom-module", ["exports"], function (exports) {
// module code
});// .babelrc
{
"plugins": [
["transform-es2015-modules-amd", {
"loose": true
}]
]
}
// Uses simple assignment instead of Object.defineProperty
define(["exports"], function (exports) {
exports.__esModule = true; // instead of Object.defineProperty
});// .babelrc
{
"plugins": [
["transform-es2015-modules-amd", {
"noInterop": true
}]
]
}
// Avoids interop helpers for default imports
define(["module"], function (_module) {
var foo = _module; // direct access instead of _module.default
});The plugin requires these dependencies:
// Internal state interface (not exported)
interface PluginState {
sources: Array<[any, any]>;
sourceNames: { [key: string]: boolean };
bareSources: any[];
hasExports: boolean;
hasModule: boolean;
ran: boolean;
}
// Template function type
interface TemplateFunction {
(replacements: { [key: string]: any }): any;
}