Skip to main content

CommonJS проти ES Modules

1. Що таке CommonJS та ES Modules

Модульна системаДе з'явиласяКлючова мета
CommonJS (CJS)У Node.js (2009)Дозволити використовувати модулі в серверному JavaScript
ES Modules (ESM)У стандарті ECMAScript (ES6, 2015)Створити нативну модульну систему для JS (браузери + Node.js)

2. Синтаксис

CommonJS:

javascript
// math.js const PI = 3.14; function add(a, b) { return a + b; } module.exports = { PI, add }; // main.js const math = require('./math'); console.log(math.add(2, 3)); // 5

Використовує:

  • require() - імпорт модулів
  • module.exports / exports - експорт модулів

ES Modules:

javascript
// math.mjs export const PI = 3.14; export function add(a, b) { return a + b; } // main.mjs import { add } from './math.mjs'; console.log(add(2, 3)); // 5

Використовує:

  • import / export - ключові слова стандарту ES6
  • Підтримується нативно браузером і Node.js (за правильного налаштування)

3. Головні відмінності

КритерійCommonJS (CJS)ES Modules (ESM)
1Синтаксисrequire, module.exportsimport, export
2Завантаження модулівДинамічне (під час виконання)Статичне (під час парсингу)
3Тип імпортуКопія значення (by value)Жива посилання (by reference)
4АсинхронністьСинхронне завантаженняАсинхронне завантаження
5Можливість "top-level await"немаєє
6Контекст thisthis вказує на module.exportsthis - undefined (строгий режим)
7Кешування модулівТак (одноразове завантаження)Так, але з іншим механізмом
8Підтримка в Node.jsЗа замовчуванням (.js)Потрібно вказати "type": "module" або використовувати .mjs
9СумісністьСтарі пакети (npm, Express тощо)Новий стандарт ECMAScript
10Використання в браузерінемає (тільки Node.js)є (у <script type="module">)

4. Статичне vs динамічне завантаження

  • CommonJS: Модуль завантажується під час виконання - require() можна викликати будь-де:

    javascript
    if (condition) { const utils = require('./utils'); }
  • ES Modules: Імпорти статичні - мають бути на початку файлу:

    javascript
    import utils from './utils.js'; // не можна всередині if

Це дозволяє ESM:

  • робити tree-shaking (видаляти невикористовуваний код);
  • оптимізувати збірку й виконання.

5. Живі посилання (Live Bindings)

ES Modules підтримують live bindings - якщо значення в модулі змінюється, імпорт теж оновлюється.

ESM:

javascript
// counter.mjs export let count = 0; export function increment() { count++; } // main.mjs import { count, increment } from './counter.mjs'; increment(); console.log(count); // 1 (оновилося)

CJS:

javascript
// counter.js let count = 0; function increment() { count++; } module.exports = { count, increment }; // main.js const { count, increment } = require('./counter'); increment(); console.log(count); // 0 (копія значення)

6. Підтримка в Node.js

CommonJS - увімкнено за замовчуванням

Файли .js вважаються CommonJS, якщо не вказано "type": "module".

ES Modules - потрібно явно увімкнути

Два способи:

  1. У package.json:
javascript
{ "type": "module" }

→ тоді всі .js файли вважаються ESM. 2. Або використовувати розширення .mjs:

javascript
node main.mjs

7. Приклад змішаного коду

Імпорт CommonJS з ESM:

javascript
// ESM import pkg from './math.cjs'; console.log(pkg.add(2, 3));

Імпорт ESM з CommonJS:

javascript
// CJS (async () => { const { add } = await import('./math.mjs'); console.log(add(2, 3)); })();

Зверни увагу: у CJS імпорт ESM тільки асинхронний через import().

8. Контекст this і глобальні змінні

ОсобливістьCommonJSES Modules
thisВказує на module.exportsundefined
Глобальні об'єкти__dirname, __filename, require, module, exportsвідсутні (можна імпортувати вручну через import.meta.url)

9. Підтримка в npm-пакетах

  • Старі пакети (express, mongoose, chalk@4) - CommonJS.
  • Нові (chalk@5, node-fetch, axios@next) - ES Modules.

При змішуванні часто виникають помилки:

javascript
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module

10. Підсумкова порівняльна таблиця

ХарактеристикаCommonJSES Modules
Формат файлів.js.mjs / .js при "type": "module"
Імпортrequire()import
Експортmodule.exportsexport
ЗавантаженняСинхроннеАсинхронне
Тип зв'язкуКопіяЖива посилання
Контекст thismodule.exportsundefined
Браузеринемаєтак
Tree-shakingнемаєтак
Top-level awaitнемаєтак
СумісністьСтарі пакетиНовий стандарт

Коротко:

CommonJS - стара, синхронна, специфічна для Node.js система модулів. ES Modules - сучасний, стандартний і крос-платформний формат, що підтримується і Node.js, і браузерами.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.