Ответ вслух Middle Модули спрашивают часто обновлено

ESM против CommonJS

Вопрос

Чем ES-модули отличаются от CommonJS? Какие практические последствия это имеет для фронтенда и Node.js?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Образцовый ответ: «ESM это стандарт языка, CommonJS исторический формат Node. Главное отличие в том, когда известны зависимости.

Что должно прозвучать в ответе

  • Статические импорты против `require` во время выполнения

  • Живые привязки против копии в `module.exports`

  • ESM асинхронен, есть top-level await и динамический `import()`

  • Tree shaking работает с ESM, CommonJS тянется целиком

  • В Node: расширения `.mjs`/`.cjs`, поле `type`, нет `__dirname` в ESM, условные `exports`

  • Совместимость: ESM импортирует CJS, CJS грузит ESM через `import()` или `require` в Node 22.12+

Что могут спросить следом

  • Что такое dual package и какие у него проблемы?
  • Почему в Node ESM нужно писать расширение файла в импорте?
  • Как поведут себя циклические зависимости в обеих системах?

Разбор

Образцовый ответ: «ESM это стандарт языка, CommonJS исторический формат Node. Главное отличие в том, когда известны зависимости. В ESM import и export статические, стоят на верхнем уровне со строковыми путями, поэтому граф зависимостей строится до выполнения: сборщик может выкинуть неиспользуемое, а ошибка в имени импорта ловится до запуска. require в CommonJS это обычный синхронный вызов, его можно поставить в if, и сборщик узнает о зависимости только в рантайме, отсюда плохой tree shaking. Второе: в ESM импорт это живая ссылка на переменную экспортёра, а в CJS я получаю объект module.exports и копирую из него значения. Третье: ESM грузится асинхронно, поддерживает top-level await, всегда строгий. Практически в Node это значит: выбирать формат через расширения или поле type, писать расширения в импортах, использовать import.meta.dirname вместо __dirname, а в библиотеках описывать поле exports с условиями для import и require. Смешивать можно: ESM спокойно импортирует CJS, а CJS с Node 22.12 может сделать require ESM-модуля без top-level await».

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.