Не все языки программирования имеют встроенную модульную систему, а в JavaScript долгое время отсутствовала эта функция.

В среде браузера можно разделить кодовую базу на несколько файлов, а затем импортировать их, используя разные теги. В течение многих лет этот подход был достаточно хорош для создания простых интерактивных веб-сайтов, а разработчикам JavaScript удавалось добиваться цели без полноценной модульной системы.

Только когда браузерные приложения JavaScript стали более сложными и экосистему захватили такие фреймворки, как jQuery, Backbone и AngularJS, сообщество JavaScript выступило с несколькими инициативами, направленными на определение модульной системы, которую можно было бы эффективно внедрить в проекты JavaScript. Наиболее успешными из них были асинхронное определение модуля (AMD), популяризированное RequireJS (nodejsdp.link/requirejs), а позднее универсальное определение модуля (UMD — nodejsdp.link/umd).

Когда Node.js был создан, он был задуман как серверная среда выполнения для JavaScript с прямым доступом к базовой файловой системе, поэтому появилась уникальная возможность представить другой способ управления модулями. Идея заключалась в том, чтобы не полагаться на HTML-теги и ресурсы, доступные через URL-адреса. Вместо этого выбор заключался в том, чтобы полагаться исключительно на файлы JavaScript, доступные в локальной файловой системе. Для своей модульной системы Node.js придумал реализацию спецификации CommonJS (иногда также называемой CJS, nodejsdp.link/commonjs), которая была разработана для предоставления модульной системы для JavaScript в средах без браузера.

CommonJS была доминирующей модульной системой в Node.js с момента ее создания, а также стала очень заметной в среде браузеров благодаря сборщикам модулей, таким как Browserify (nodejsdp.link/browserify) и webpack (nodejsdp.link/webpack ).

В 2015 году, с выпуском ECMAScript 6 (также называемого ECMAScript 2015 или ES2015), наконец-то появилось официальное предложение для стандартной модульной системы: модули ESM или ECMAScript. ESM привносит много инноваций в экосистему JavaScript и, среди прочего, пытается преодолеть разрыв между тем, как модули управляются в браузерах и на серверах.

ECMAScript 6 определил только формальную спецификацию ESM с точки зрения синтаксиса и семантики, но не предоставил никаких деталей реализации. Разным браузерным компаниям и сообществу Node.js потребовалось несколько лет, чтобы разработать надежную реализацию спецификации. Node.js поставляется со стабильной поддержкой ESM, начиная с версии 13.2.

На момент написания статьи все думали, что ESM станет де-факто способом управления модулями JavaScript как в браузере, так и на сервере. Однако сегодняшняя реальность такова, что большинство проектов по-прежнему в значительной степени полагаются на CommonJS, и ESM потребуется некоторое время, чтобы догнать его и в конечном итоге стать доминирующим стандартом.

Чтобы предоставить всесторонний обзор шаблонов, связанных с модулями, в Node.js, мы обсудим их в контексте CommonJS, а затем, в следующих статьях, вернемся к нашим знаниям с помощью ESM.

Цель этой статьи — научить вас работать с обеими модульными системами, но в остальных статьях мы будем использовать только ESM для наших примеров кода. Идея состоит в том, чтобы побудить вас максимально использовать ESM, чтобы ваш код был более перспективным.

Если вы читаете эти статьи через несколько лет после их публикации, вы, вероятно, не слишком беспокоитесь о CommonJS и, возможно, захотите сразу перейти к части ESM. Это, вероятно, хорошо, но мы все же рекомендуем вам просмотреть весь список статей, потому что понимание CommonJS и его характеристик, безусловно, поможет вам лучше понять ESM и его сильные стороны.