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

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