ES modules and CommonJS — two module systems in one runtime¶
Level: 101 · for anyone who has met both require and import
Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The questions below are what the finished page has to answer.
One line: Node settles a file's module system before running it — .mjs is ESM, .cjs is CommonJS, .js follows the nearest package.json "type" or else its own syntax — and then one line differs: typeof require is "function" in CommonJS, "undefined" in ESM.
Keywords: module.exports, .mjs, .cjs, CommonJS
What the finished page will answer¶
- What do
typeof require,typeof __filenameand a top-levelthisprint in a.cjsfile, and in a.mjsfile with the same line? - Which system does Node choose for
.mjs, for.cjs, and for a.jsfile with and without"type": "module"in the nearestpackage.json? - What happens to a
.jsfile that has no"type"to follow but usesimport, and what does theMODULE_TYPELESS_PACKAGE_JSONwarning say? - Why does assigning to an undeclared variable create a global in a
.cjsfile but throw aReferenceErrorin a.mjsfile? - What stands in for
__filename,__dirname,requireandmodule.exportsonce a file is an ES module?
Examples it will need¶
-
esm_and_commonjs_same_line_sh.sh— the same line run as same.cjs, same.mjs and same.js, then as same.js again after a package.json with "type": "module" appears -
esm_and_commonjs_detection_sh.sh— a .js file that uses import, run with no package.json and then beside one without "type", with the warning Node writes to stderr
See also¶
- Scripts and modules — the same code under script rules and under module rules
- Strict mode — the rules every ES module runs under, whether it asks or not
package.json— the type field, and the rest of what package.json decidesrequireand ES modules — loading one system from the other- Rust: Packages and crates ↗ — the unit Rust builds: a Cargo package and its crates, not a file
- Rust: One module per file ↗ — how Rust maps files to modules, with a single system