Вступление
На протяжении многих лет экосистема компонентов JavaScript постоянно растёт. Количество компонентов просто фантастично. Но большое количество различных компонентов вызывает определённые трудности в процессе их использования, так как они могут иметь различные механизмы интеграции. Начинающие разработчики достаточно быстро понимают, что не все модули созданы таким образом, что бы хорошо работать друг с другом.
Для решения этих проблем появились конкурирующие между собой спецификации модулей AMD и CommonJS, которые позволяют разработчикам писать свой код в согласованном изолированном и модульном режиме, что бы не «загрязнить экосистему».
AMD
AMD (Asynchronous module definition ) — что дословно переводится как «Асинхронное определение модуля», используется с RequireJS и является самым популярным.
Ниже модуль foo
с одной зависимостью jquery
define(['jquery'], function ($) { // методы function myFunc(){}; // публичные методы return myFunc; });
И немного более сложный пример с несколькими зависимостями и несколькими открытыми методами:
define(['jquery', 'underscore'], function ($, _) { // методы function a(){}; // приватный метод, так как не возвращается (смотрите ниже) function b(){}; // публичный метод, так как возвращается function c(){}; // публичный метод, так как возвращается // публикуем публичные методы return { b: b, c: c } });
Функция define
фактически занимается публикацией модуля. В качестве первого аргумента она принимает массив зависимостей, вторая часть — это функция обратного вызова, которая будет выполнена только в том случае, если в проекте присутствуют все модули, описанные в массиве зависимостей. Сама функция define
определена в пакете-загрузчике, таких как RequireJS, который вам придётся использовать, если вы хотите использовать модули типа AMD.
Обратите внимание на то, что модули, которые описаны в массиве зависимостей, передаются в функцию именно в том порядке в котором указаны. Т.е. 'jquery'->$
а 'underscore'->_
. Такой вариант позволяет использовать в функции собственные переменные. Вы можете передать jquery
не в $
а в $$
и в использовать именно $$
в своём модуле.
И обратите внимание на то, что вы не можете ссылаться на переменные $
и _
вне функции, потому что она изолирована от другого кода. Это собственно цель!
CommonJS
CommonJS — это стиль, с которым вы можете быть знакомы, если вы пишите что-нибудь под NodeJs. Модули в подобном стиле можно использовать и на стороне клиента в браузере при помощи таких библиотек как Browserify.
Использую тот же формат, что и раньше, давайте посмотрим на модуль foo
в стиле Common JS:
// зависимости var $ = require('jquery'); // методы function myFunc(){}; // публикация публичного метода (одиночная) module.exports = myFunc;
И наш более сложный пример, с несколькими зависимостями и несколькими публичными методами:
// зависимости var $ = require('jquery'); var _ = require('underscore'); // методы function a(){}; // приватный метод, так как не возвращается (смотрите ниже) function b(){}; // публичный метод, так как возвращается function c(){}; // публичный метод, так как возвращается // публикация публичных методов module.exports = { b: b, c: c };
UMD
UMD — Определение универсального модуля. Поскольку стили CommonJS и AMD были одинаково популярны, похоже, пока нет единого мнения. Это привело к появлению «универсального» шаблона, который поддерживает оба стиля.
Образец, по общему признанию, уродлив, но совместим как с AMD, так и с CommonJS, а также поддерживает определение «глобальных» переменных старого стиля (стиль «когда твой папка писал под ie8») :
(function (root, factory) { if (typeof define === 'function' & define.amd) { // AMD define(['jquery'], factory); } else if (typeof exports === 'object') { // Node, CommonJS-like module.exports = factory(require('jquery')); } else { // Глобальные переменные. root это windows root.returnExports = factory(root.jQuery); } }(this, function ($) { // методы function myFunc(){}; // публикация публичных методов return myFunc; }));
И наш более сложный пример, с несколькими зависимостями и несколькими публичными методами:
(function (root, factory) { if (typeof define === 'function' & define.amd) { // AMD define(['jquery', 'underscore'], factory); } else if (typeof exports === 'object') { // Node, CommonJS-like module.exports = factory(require('jquery'), require('underscore')); } else { // Глобальные переменные. root это windows root.returnExports = factory(root.jQuery, root._); } }(this, function ($, _) { // methods function a(){}; // приватный метод, так как не возвращается (смотрите ниже) function b(){}; // публичный метод, так как возвращается function c(){}; // публичный метод, так как возвращается // exposed public methods return { b: b, c: c } }));
Это статейка по большей части для личных нужд, оригинал если что тут.
Просто зашел сюда в пол пятого утра, т.к. не давала покоя мысль, почему в реакте при установке из npm он делится на две папки внутри cjs/umd, теперь я знаю больше *_*
пс: знаю, ты удивлен, что кто-то оставил комментарий, я бы тоже удивилс 🙂
🙂 Ну js это просто мейнстрим. Странно что вообще ты сюда как то попал)
Я с первой страницы гугла попал :—)
Спасибо за ликбез! Я хоть и бэкендер и ненавижу JS, но знать это всё равно полезно.