Node.js Module Import
When you start writing a Node.js project, one of the first problems you encounter is how to import modules.
In Node.js, modules are reusable JavaScript files that communicate with each other through import and export.
The Node.js ecosystem mainly supports two module systems:CommonJSand ES Modules (ESM)。
| Module System | Specification | File Extension | Import Method | Export Method |
|---|---|---|---|---|
| CommonJS | Early Node.js usage | .js |
require() |
module.exports / exports |
| ES Module (ESM) | ECMAScript Standard | .mjsor"type": "module" |
import |
export / export default |
CommonJS Module System
CommonJS is the earliest and most widely used module system in Node.js. It uses synchronous loading, which means that when a module is loaded, it blocks program execution until the loading is complete.
Import and Export
In CommonJS, you userequire()function to import modules, and usemodule.exportsorexportsobject to export modules.
Export methods:
math.js file code:
function add(a, b) {
return a + b;
}
module.exports = { add };
// Or: exports.add = add;
Import methods:
Example
const math = require('./math.js');
console.log(math.add(2, 3)); // 5
For a module to allow external access to its content, it needs to use module.exports or exports to export it:
Example
const name = 'Alice';
const age = 30;
// Method 1: Use module.exports to export a single object or value
module.exports = {
name: name,
age: age,
sayHello: () => {
console.log(`Hello, my name is ${name}.`);
}
};
// Method 2: Use exports to export multiple named variables
// exports is a reference to module.exports
exports.name = name;
exports.age = age;
exports.sayHello = () => {
console.log(`Hello, my name is ${name}.`);
};
Import methods:
Example
const user = require('./user.js');
console.log(user.name); // Output: Alice
user.sayHello(); // Output: Hello, my name is Alice.
// You can also destructure directly
const { name, age } = require('./user.js');
console.log(name); // Output: Alice
CommonJS features:
- Synchronous loading: Suitable for server-side environments because modules are usually in the local file system and load quickly.
- Runtime loading:
require()You can call it anywhere in the code, which allows you to dynamically load modules based on conditions. - Caching mechanism:
require()Loaded modules are cached. When imported a second time, they are read directly from the cache, avoiding repeated loading.
ES Module (ESM) Specification
ESM is the official JavaScript module standard. It uses asynchronous loading and is the first choice for browsers and modern Node.js applications.
In ESM, you useimportstatement to import modules, and useexportstatement to export modules.
Enabling ESM:To use ESM in Node.js, you need to add"type": "module", or change the file extension to.mjs。
// package.json
{
"type": "module"
}
Exporting modules:
Example
export function add(a, b) {
return a + b;
}
export default function multiply(a, b) {
return a * b;
}
Importing modules:
Example
import multiply, { add } from './math.mjs';
console.log(add(2, 3)); // 5
console.log(multiply(2, 3)); // 6
How to enable:
Use file extension.mjs
Or add this in package.json:
{ "type": "module" }
ESM supports two export methods: named exports and default export.
Example
// Named export
export const name = 'Bob';
export const age = 25;
// Default export
const sayHello = () => {
console.log(`Hello, my name is ${name}.`);
};
export default sayHello;
Import methods:
Example
// Import named export
import { name, age } from './user.mjs';
console.log(name); // Output: Bob
// Import default export
import sayHello from './user.mjs';
sayHello(); // Output: Hello, my name is Bob.
// Import named and default exports together
import sayHello, { name } from './user.mjs';
console.log(name);
sayHello();
// Import all named exports as properties of an object
import * as user from './user.mjs';
console.log(user.name);
user.default(); // The default export will be the default property
ESM features:
- Asynchronous loading: It is asynchronous by default and does not block the main thread, making it more suitable for browser environments, but in Node.js it usually behaves as synchronous loading.
- Static analysis:
importandexportstatements can determine module dependencies before code execution, allowing tools (such as Webpack, Vite) to perform better optimizations (such asTree Shaking)。 - Strict mode: ESM modules run in strict mode by default.
Differences Between CommonJS and ESM
| Item | CommonJS | ESM |
|---|---|---|
| Syntax | require / module.exports |
import / export |
| Loading mechanism | Synchronous loading at runtime | Static loading at compile time |
| Default support | Supported by default in Node.js | Need.mjsor"type": "module" |
| Suitable scenarios | Backend scripts, legacy projects | Modern frontend and backend projects, Tree-shaking |
| Can they be mixed? | Cannot be mixed directly (requires additional configuration) | Cannot be mixed directly (requires additional configuration) |
Mixed Usage
Node.js supports coexistence of both module systems in newer versions. You can use CommonJS and ESM together in the same project, but you need to note the following:
- ESM cannot directly use
require()andmodule.exports。 - CommonJS cannot directly use
importandexport。 -
If you want to import a CommonJS module in ESM, you can directly use
importstatement, and ESM will treat it as a default export.// commonjs_module.js module.exports = { data: 'hello' }; // esm_module.mjs import commonModule from './commonjs_module.js'; console.log(commonModule.data); // 输出: hello -
If you want to import an ESM module in CommonJS, you need to use dynamic
import()function.// esm_module.mjs export const name = 'Bob'; // commonjs_module.js async function loadESM() { const { name } = await import('./esm_module.mjs'); console.log(name); } loadESM();
Best Practice Suggestions
For new projects,it is strongly recommended to use ES Modules (ESM). It is not only the official standard for JavaScript, but also has better compatibility with modern frontend toolchains (such as Vite, Next.js), and can fully utilize optimization techniques like Tree Shaking to reduce the bundled code size.
If you are maintaining an old CommonJS project and do not need ESM features, you can continue using CommonJS. However, if you need to introduce new dependencies or take advantage of ESM's new features, you can consider migrating gradually or using mixed mode as a transition.
Other Extensions