CommonJS - система модулів, з якою Node.js жив до ES-модулів:
// CommonJS
const path = require('node:path');
module.exports = { formatPrice };
// ES-модулі
import path from 'node:path';
export { formatPrice };
Ключові відмінності:
| CommonJS | ES-модулі | |
|---|---|---|
| завантаження | синхронне, під час виконання | асинхронне, граф будується до виконання |
require/import |
звичайна функція, будь-де в коді, шлях може бути змінною | лише на верхньому рівні, шлях - константа (крім import()) |
| що імпортується | копія значення module.exports на момент виклику |
живе посилання на експортовану змінну |
this на верхньому рівні |
module.exports |
undefined |
__dirname, __filename |
є | немає: import.meta.dirname, import.meta.filename |
top-level await |
ні | так |
| розширення в шляху | можна опустити | обов'язкове для відносних шляхів (./utils.js) |
Як Node.js вирішує, що це за модуль:
.mjs- завжди ES-модуль,.cjs- завжди CommonJS;.js- залежно від поля"type"у найближчомуpackage.json:"module"- ES-модулі,"commonjs"чи відсутність поля - CommonJS.
Laravel-проєкти мають "type": "module" у package.json, тож vite.config.js і скрипти пишуться як ES-модулі.
Взаємодія:
- ES-модуль може імпортувати CommonJS:
module.exportsстає експортом за замовчуванням; - CommonJS імпортує ES-модуль через
require()- з Node.js 22.12 це працює без прапорців, якщо модуль не використовує top-levelawait. Раніше лишався тільки асинхроннийawait import(); - пакети з подвійною збіркою містять обидва варіанти й вибирають потрібний через поле
exportsуpackage.json.
Навіщо ES-модулі, якщо CommonJS працював:
- один стандарт для браузера і сервера;
- статичний аналіз: збирачі й редактори знають залежності без виконання коду - tree shaking, точний автоімпорт, перевірка неіснуючих експортів;
- асинхронне завантаження підходить для браузера і дає змогу top-level
await.
Типові помилки при переході: require is not defined in ES module scope, __dirname is not defined, Cannot use import statement outside a module - усі означають, що файл інтерпретується не в тій системі модулів, ніж написаний.