Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим CommonJS (require) відрізняється від ES-модулів у Node.js?

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-level await. Раніше лишався тільки асинхронний 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 - усі означають, що файл інтерпретується не в тій системі модулів, ніж написаний.

Докладніше в документації: Node.js: ES-модулі

Схожі питання