There's a wide variety of supported forms of require(..)
and module.exports
expressions that Moduloze can recognize and convert, and a lot of factors that control which output is created. The goal in these conversion guides is to try to document as much of that detail as practical.
Consider the following CJS code (in a file like ./src/test.js
):
var Whatever = require("./src/whatever.js");
var { Something } = require("./src/something.js");
var anotherVal = require("./src/another.js").another();
module.exports.whatever = Whatever();
Object.assign(module.exports,{
Something,
Another: anotherVal,
});
And consider the build command (either directly in code as shown, or via the CLI) essentially looking like this:
var config = {
buildUMD: true,
buildESM: true,
ignoreUnknownDependency: true
};
var depMap = {
"./src/test.js": "TestModule",
"./src/whatever.js": "Whatever",
"./src/another.js": "Another"
};
var results = build(
config,
"./src/test.js",
testModuleCode,
depMap
);
The converted ESM code (in results.esm.code
) will look like this:
import Whatever from "./src/whatever.mjs";
import { Something } from "./src/something.js";
import _imp from "./src/another.mjs";
var anotherVal = _imp();
let _exp = Whatever();
export { _exp as whatever };
let _exp2 = {};
Object.assign(_exp2, {
Something,
Another: anotherVal
});
export default _exp2;
For more information on all the nuances of this conversion (and all other forms), see the ESM Conversion Guide.
The converted UMD code (in results.umd.code
) will look like this:
/* NOTE: this is all auto-generated UMD wrapper stuff */
/* ************************************* */
(function UMD(name, context, dependencies, definition) {
if (typeof define === "function" && define.amd) {
dependencies = Object.keys(dependencies).map(p => p.replace(/^\.\//, ""));
define(name, dependencies, definition);
} else if (typeof module !== "undefined" && module.exports) {
dependencies = Object.keys(dependencies).map(p => require(p));
module.exports = definition(...dependencies);
} else {
dependencies = Object.values(dependencies).map(n => context[n]);
context[name] = definition(...dependencies);
}
})("TestModule", typeof globalThis != "undefined" ? globalThis : typeof global != "undefined" ? global : typeof window != "undefined" ? window : typeof self != "undefined" ? self : new Function("return this")(), {
"./src/whatever.js": "Whatever",
"./src/something.js": "Mz_540737562",
"./src/another.js": "Another"
}, function DEF(Whatever, Mz_540737562, Another) {
/* ************************************* */
/* Note: this is where your module's code goes */
var {
Something
} = Mz_540737562;
var anotherVal = Another.another();
let _exp2 = {};
_exp2.whatever = Whatever();
Object.assign(_exp2, {
Something,
Another: anotherVal
});
return _exp2;
});
Note: The code comments and extra blank lines are added here only for easier readability; they're not actually included in the output.
For more information on all the nuances of this conversion (and all other forms), see the UMD Conversion Guide.
The "Unsupported" section of the README covers two major limitations on supported forms:
-
require(..)
must have a single string literal (delimited with'
or"
, not`
) -
require(..)
andmodule.exports
must be part of a statement in the top-level scope of the program
In addition, there are some other limitations to be aware of:
-
Circular dependencies are impossible in UMD format; so by default, Moduloze complains if a dependency cycle is detected. If you're only building ESM format, and want to let ESM manage the circular dependency resolution, you can turn on the
ignoreCircularDependency
configuration. -
Multiple re-assignments of
module.exports
in the same file is not allowed, since each re-assignment is translated in ESM as aexport default ..
, and only one of those is allowed per ESM module. This would be a red flag anyway; if you find this error raised in your conversion, it likely means the source file is confusingly stepping on its own toes with its conflictingmodule.exports
behavior.