babel-plugin-transform-commonjs
babel-plugin-transform-commonjs copied to clipboard
IIFE transformed modules are incompatible es module babel plugins
IIFE transformed modules are incompatible with babel plugins which transform es modules.
Sort of a mouthful but I'll try to explain what's happening below.
Consider this CJS module
this.name = 'true';
Running this through transform-commonjs
wraps it in a IIFE to preserve the this
module context.
var module = {
exports: {}
};
var exports = module.exports;
(function () {
this.name = 'true';
}).call(module.exports);
export default module.exports;
If we use another ESM babel transform (such as transform-modules-systemjs
) it causes nested duplication of code
System.register([], function (_export2, _context) {
"use strict";
return {
setters: [],
execute: function () {
System.register([], function (_export, _context) {
"use strict";
var module, exports;
return {
setters: [],
execute: function () {
module = {
exports: {}
};
exports = module.exports;
(function () {
this.name = 'true';
}).call(module.exports);
_export("default", module.exports);
}
};
});
}
};
});
The issue seems to be coming from this line in the ThisExpression
branch:
https://github.com/tbranyen/babel-plugin-transform-commonjs/blob/6b3ac9bf0870a995b67d3d93f60735ce798f3950/lib/index.ts#L62
I'm not too familiar with babel's helper functions. What's your thoughts on this? Is there another method which will prevent duplication of the program?
Is the nested duplication breaking anything, or does it just look inefficient?
For SystemJS in this case, it breaks dependency loading since the System.register
call is duplicated.
I use multi-pass to solve this problem. babel.transformFile
+ babel.transformAst
.
Replacing top level this
exports with the exports
keyword worked for me.
https://github.com/tbranyen/babel-plugin-transform-commonjs/pull/16/files#diff-13b5b151431c7e7a17f273559ed212d5R316
Although this implementation may not cover all use cases and doesn't handle early return
s