CommonJS проти es модулів у Node.js
Модульні системи в Node.js
Node.js підтримує дві модульні системи: оригінальну CommonJS (CJS) та сучасну ES Modules (ESM). Розуміння відмінностей є важливим для написання сумісного коду Node.js.
CommonJS (CJS)
За замовчуванням модульна система в Node.js з моменту її створення.
js
// math.js — експорт
function add(a, b) { return a + b; }
module.exports = { add };
// main.js — імпорт
const { add } = require('./math');
console.log(add(2, 3)); // 5Ключові характеристики:
- Використовує
require()/module.exports - Синхронне завантаження (блокує, поки модуль не буде завантажено)
- Завантажується під час виконання
- За замовчуванням у файлах
.js, якщо в package.json не вказано"type": "module"
ES Modules (ESM)
Офіційний стандарт ECMAScript, тепер повністю підтримується в Node.js 12+.
js
// math.mjs — експорт
export function add(a, b) { return a + b; }
// main.mjs — імпорт
import { add } from './math.mjs';
console.log(add(2, 3)); // 5Ключові характеристики:
- Використовує синтаксис
import/export - Асинхронне завантаження (краще для tree-shaking)
- Статично аналізується під час парсингу
- Використовуйте розширення
.mjsАБО встановіть"type": "module"в package.json
Таблиця порівняння
| Особливість | CommonJS | ES Modules |
|---|---|---|
| Синтаксис | require() / module.exports | import / export |
| Завантаження | Синхронне | Асинхронне |
| Аналіз | Під час виконання | Статичний (під час парсингу) |
| Tree-shaking | ❌ | ✅ |
Top-level await | ❌ | ✅ |
__dirname / __filename | ✅ | ❌ (використовуйте import.meta.url) |
| За замовчуванням в Node.js | ✅ | З "type":"module" |
Взаємодія
js
// ESM може імпортувати CJS:
import { add } from './math.cjs'; // ✅
// CJS не може require() ESM:
const { add } = require('./math.mjs'); // ❌ Помилка!
// CJS може використовувати динамічний import() для ESM:
const { add } = await import('./math.mjs'); // ✅Увімкнення ESM
Опція 1: Використовуйте розширення .mjs
Опція 2: Додайте до package.json:
json
{
"type": "module"
}Отримання __dirname в ESM
js
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);Резюме
Використовуйте ESM для нових проектів (це стандарт, підтримує tree-shaking та top-level await). Використовуйте CommonJS при роботі з застарілим кодом або пакетами, які ще не підтримують ESM.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.