Studies on the differences between ESModules and CommonJS.
- It only imports modules using the
import
syntax. You can't userequire
syntax. It would throw an errorReferenceError: require is not defined in ES module scope, you can use import instead
. - Bundlers don’t know how to work with ESM modules that use the
require
syntax. - CJS is the default module system. To change it to ESM, set the
type
frompackage.json
tomodule
. - If module is using only named exports (no default export) and the other module is defaul importing the module, it throws an error
SyntaxError: The requested module './A.mjs' does not provide an export named 'default'
. The module exporting should export default too or the second module should named import the first one.
- It only requires modules using the
require
syntax. You can't use theimport
syntax. It throws an exceptionSyntaxError: Cannot use import statement outside a module
. - Can’t use ESM in CJS. It throws an exception: Must use import to load an ES Module.
- In Node, CJS is the default module system. By default, the
package.json
usescommonjs
as thetype
's value. - The
require
syntax is synchronous: there's no callback or promise.
ESM can default import CJS modules even when the CJS module has no default exports (only named exports). It treats the module as an object, so it need to access its "attribute".
// ModuleA.js
module.exports.A = 1;
// ModuleB.js
import ModuleA from './ModuleA.js';
ModuleA.A; // 1
ESM can named import CJS modules.
// ModuleA.js
module.exports.A = 1;
// ModuleB.js
import { A } from './ModuleA.js';
A; // 1
CJS can't import/require ESM. It throws an exception: Must use import to load an ES Module
. If trying to use the import
syntax, it will throw another exception: SyntaxError: Cannot use import statement outside a module
.
From CommonJS:
const a = 1;
const b = 2;
const c = 3;
module.exports = {
a,
b,
c,
};
To ESModule:
export const a = 1;
export const b = 2;
export const c = 3;
From CommonJS:
const a = 1;
module.exports = a;
To ESModule:
const a = 1;
export default a;
From CommonJS:
const { a, b, c } = require('./module');
To ESModule:
import { a, b, c } from './module';
From CommonJS:
const a = require('./module);
To ESModule:
import a from './module';
From CommonJS:
const {
a: { b },
} = require('./module');
From ESModule:
// import { a: { b } } from './module'; --> Syntax Error
import { a } from './module';
const { b } = a;