babel-plugin-transform-amd-to-commonjs
Babel plugin that transforms AMD to CommonJS.
Check out the example project, which uses this plugin to allow jest to synchronously require
AMD modules.
Usage
npm install --save-dev babel-plugin-transform-amd-to-commonjs
Add the transform to your .babelrc:
{
"plugins": ["transform-amd-to-commonjs"]
}
Examples
Define
Input:
define(['jquery', 'underscore', 'myModule'], function($, _) {
return {
};
});
Output:
module.exports = function() {
var $ = require('jquery');
var _ = require('underscore');
require('myModule');
return {
};
}();
Require
Input:
require(['jquery', 'underscore', 'myModule'], function($, _) {
require(['anotherModule'], function(anotherModule) {
});
});
Output:
(function() {
var $ = require('jquery');
var _ = require('underscore');
require('myModule');
(function() {
var anotherModule = require('anotherModule');
})();
})();
Details
Supported Versions
Only Node.js >= 6 is supported. For Node.js 4, please use version 0.2.2:
npm install --save-dev babel-plugin-transform-amd-to-commonjs@0.2.2
AMD
AMD is interpreted as described by the AMD specification.
- Only top-level calls to a
define
function will be transformed. - All calls to
require
where it is given an array of dependencies as its first argument will be transformed. - Explicitly requiring
require
, module
, and exports
in an AMD module will not generate a call to require, but instead defer to the global require, module, and exports assumed to be in the CommonJS environment you are transforming to.
- The module name (optional first argument to
define
) is ignored, since the module ID in CommonJS is determined by the resolved filename.
Upgrading Versions
1.0.0
- Versions >= 0.2.1 and < 1.0.0 support Node.js 4.
1.0.0 and above only support Node.js 6 and above.
To upgrade to >= 1.0.0, first upgrade to Node.js >= 6.
- If everything works fine with < 1.0.0, you should just be able to drop in >= 1.0.0 after upgrading Node.js.
If you have any issues, there is one more edge-case breaking change that might be affecting you (but probably is not):
-
= 1.0.0 accounts for the case where you're using a combination of return statements and module/exports to define the exports of your AMD modules.
Earlier versions don't account for this case, so if you're upgrading, make sure that each AMD module only uses either return statements or module/exports to define its exports.
See #26 and the caveats section of the README for more details.
Caveats
One module per file
Make sure that you have only one AMD module defined per file, otherwise you'll experience strange results once transformed to the CommonJS format.
Listing module dependencies and callbacks inline
The following will not be transformed, since the plugin does not traverse the arguments to define or require:
var dependencies = ['one', 'two'];
var factory = function(one, two) {
one.doStuff();
return two.doStuff();
};
define(dependencies, factory);
If you want to be able to define your modules as above, please submit an issue. Otherwise, please define your modules as:
define(['one', 'two'], function(one, two) {
one.doStuff();
return two.doStuff();
});
Injecting require
, module
, or exports
as dependencies
It is strongly advised to simply use return statements to define your AMD module's exports.
That being said, the plugin takes into account the cases where you may have injected them as dependencies.
Beware of the following gotchas when using this pattern:
-
If you're injecting module
, exports
, and/or require
as dependencies, they must be injected as string literals,
otherwise you'll end up with things like require('module')
.
-
Returning any value other than undefined
from a factory function will override anything you assign to module
or exports
.
This behaviour is in accordance with the AMD specification.
Unless you're doing something really weird in your modules, you don't have to worry about this case, but the plugin handles it by performing a check as needed on the return value of the factory function.
For example:
Input (AMD):
define(['module'], function(module) {
module.exports = { hey: 'boi' };
return { value: 22 };
});
Output (CommonJS):
var amdDefineResult = function() {
module.exports = { hey: 'boi' };
return { value: 22 };
}();
typeof amdDefineResult !== 'undefined' && (module.exports = amdDefineResult);
Note that { value: 22 }
is correctly exported in both cases. Without the typeof amdDefineResult !== 'undefined'
check in place, { hey: 'boi' }
would have been erroneously exported once transformed to CommonJS.
This pattern is only used if necessary. The variable amdDefineResult
is generated to be unique in its scope.