Трудно представить себе времена до NodeJS, но еще более темные времена были до CommonJS. Не совсем уверены, что такое CommonJS? Ну что, начнем с середины?
CommonJS был запущен инженером Mozilla Кевином Дангуром в январе 2009 года для решения проблемы отсутствия общепринятых методов модульности в программировании на Javascript. Как они этого добились?
«Группа CommonJS определила формат модуля для решения проблем с областью действия JavaScript, убедившись, что каждый модуль выполняется в своем пространстве имен. Это достигается за счет принуждения модулей к явному экспорту тех переменных, которые они хотят предоставить «вселенной», а также путем определения других модулей, необходимых для правильной работы».
— Документы Webpack
Почему модульность? У модульности есть четыре существенных преимущества. Во-первых, это возможность повторного использования. Модули позволяют импортировать код и использовать его в других модулях, или несколько модулей можно экспортировать в пакет и устанавливать в разных средах. Далее, модули предоставляют нам компонуемость, потому что код можно явно определить и быстро удалить. Работа в модулях изолирует разделы методов, поэтому работу можно создавать (а затем исправлять) отдельно. Несколько разработчиков могут работать над изолированными модулями независимо друг от друга и избегать конфликтов слияния. Наконец, модульность обеспечивает организацию программы за счет естественных точек разделения. Написание большого количества кода и переменных менее подвержено ошибкам благодаря модульности, поскольку она не загрязняет глобальное пространство имен и позволяет избежать коллизий.
Давным-давно, до модульности, если разработчики хотели сделать код из других файлов доступными друг для друга, они обращались к переменным и функциям из глобального объекта окна. Затем, чтобы скомпилировать весь код в браузере, каждый файл включается с тегами script в файл index.html. Эта система не очень многоразовая, и большая часть программы находится в той же области. Но должен был быть лучший способ.
Появились немедленно вызываемые функциональные выражения. IIFE — это анонимные функции, заключенные в круглые скобки. Затем, как и для любой другой функции, для ее вызова мы добавляем еще одну пару круглых скобок в ее конец. IIFE значительно очищает глобальное пространство имен, но теги script по-прежнему необходимы. Там должен быть лучший способ!
Наконец, у нас есть CommonJS. CommonJS делает каждый файл своим модулем. Затем каждый файл явно определяет импорт (или зависимости) и явный экспорт, которые будут доступны для любого другого файла. Взгляните на явно определенный экспорт ниже.
// customers.js var customers = ["Rachel", "Galen", "Charles"] module.exports = { getCustomers: function () { return users }, sortCustomers: function () { return users.sort() }, firstCustomer: function () { return users[0] } }
Для простоты любая информация о модуле может быть помещена в объект. Затем все, что мы хотим экспортировать из модуля, мы можем прикрепить к module.exports
! Теперь посмотрим, как мы можем импортировать.
// acounting.js const customers = require('./users') customers.getCustomers() // ["Rachel", "Galen", "Charles"] customers.sortCustomers() // ["Charles", "Galen", "Rachel"] customers.firsCustomer() // ["Charles"]
Если вы раньше использовали Node, вы узнаете стандарт CommonJS. Node использует вариант этой спецификации. Однако, в отличие от Node, браузеры естественным образом не поддерживают CommonJS. Другим недостатком является то, что CommonJS загружает свои модули синхронно. Ба! Все эти преимущества и еще две проблемы. Мы можем исправить это с помощью сборщиков модулей, таких как Webpack. Если мы игнорируем сложность, сборщик модулей, по сути, превращает ваш код из нескольких файлов в один.
payroll.js ------> | | customers.js ----> | Bundler | -> bundle.js accounting.js ---> | |
После того, как все файлы объединены в один, что тогда? Как они это делают? Ну, с одним большим IIFE!
В заключение, модули CJS представляют собой повторно используемый код, доступный для зависимых файлов. Он достигает всех наших целей организованного управления зависимостями, разделения задач, изоляции и компонуемости. Хотя с 2009 года многое изменилось, CommonJS проложил путь к современным методам модульности, которые являются требованием любой программы, написанной сегодня.