JavaScript | Что такое AMD, CommonJS, и UMD?

JavaScript | Что такое AMD, CommonJS, и UMD?

Reading Time: 1 minute

Вступление

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

Для решения этих проблем появились конкурирующие между собой спецификации модулей AMD и CommonJS, которые позволяют разработчикам писать свой код в согласованном изолированном и модульном режиме, что бы не «загрязнить экосистему».

AMD

AMD (Asynchronous module definition ) — что дословно переводится как «Асинхронное определение модуля», используется с RequireJS и является самым популярным.

Ниже модуль foo с одной зависимостью jquery

<br />
define(['jquery'], function ($) {<br />
    //    методы<br />
    function myFunc(){};</p>
<p>    //    публичные методы<br />
    return myFunc;<br />
});<br />

И немного более сложный пример с несколькими зависимостями и несколькими открытыми методами:

<br />
define(['jquery', 'underscore'], function ($, _) {<br />
    //    методы<br />
    function a(){};    //    приватный метод, так как не возвращается (смотрите ниже)<br />
    function b(){};    //    публичный метод, так как возвращается<br />
    function c(){};    //    публичный метод, так как возвращается</p>
<p>    //   публикуем публичные методы<br />
    return {<br />
        b: b,<br />
        c: c<br />
    }<br />
});<br />

Функция define фактически занимается публикацией модуля. В качестве первого аргумента она принимает массив зависимостей, вторая часть — это функция обратного вызова, которая будет выполнена только в том случае, если в проекте присутствуют все модули, описанные в массиве зависимостей. Сама функция define определена в пакете-загрузчике, таких как RequireJS, который вам придётся использовать, если вы хотите использовать модули типа AMD.

Обратите внимание на то, что модули, которые описаны в массиве зависимостей, передаются в функцию именно в том порядке в котором указаны. Т.е. 'jquery'->$ а 'underscore'->_ . Такой вариант позволяет использовать в функции собственные переменные. Вы можете передать jquery не в $ а в $$ и в использовать именно $$ в своём модуле.
И обратите внимание на то, что вы не можете ссылаться на переменные $ и _ вне функции, потому что она изолирована от другого кода. Это собственно цель!

CommonJS

CommonJS — это стиль, с которым вы можете быть знакомы, если вы пишите что-нибудь под NodeJs. Модули в подобном стиле можно использовать и на стороне клиента в браузере при помощи таких библиотек как Browserify.

Использую тот же формат, что и раньше, давайте посмотрим на модуль foo в стиле Common JS:

<br />
//    зависимости<br />
var $ = require('jquery');</p>
<p>//    методы<br />
function myFunc(){};</p>
<p>//    публикация публичного метода (одиночная)<br />
module.exports = myFunc;<br />

И наш более сложный пример, с несколькими зависимостями и несколькими публичными методами:

<br />
//    зависимости<br />
var $ = require('jquery');<br />
var _ = require('underscore');</p>
<p>//    методы<br />
function a(){};    //    приватный метод, так как не возвращается (смотрите ниже)<br />
function b(){};    //    публичный метод, так как возвращается<br />
function c(){};    //    публичный метод, так как возвращается</p>
<p>//     публикация публичных методов<br />
module.exports = {<br />
    b: b,<br />
    c: c<br />
};<br />

UMD

UMD — Определение универсального модуля. Поскольку стили CommonJS и AMD были одинаково популярны, похоже, пока нет единого мнения. Это привело к появлению «универсального» шаблона, который поддерживает оба стиля.

Образец, по общему признанию, уродлив, но совместим как с AMD, так и с CommonJS, а также поддерживает определение «глобальных» переменных старого стиля (стиль «когда твой папка писал под ie8») :

<br />
(function (root, factory) {<br />
    if (typeof define === 'function' &amp; define.amd) {<br />
        // AMD<br />
        define(['jquery'], factory);<br />
    } else if (typeof exports === 'object') {<br />
        // Node, CommonJS-like<br />
        module.exports = factory(require('jquery'));<br />
    } else {<br />
        // Глобальные переменные. root это windows<br />
        root.returnExports = factory(root.jQuery);<br />
    }<br />
}(this, function ($) {<br />
    //    методы<br />
    function myFunc(){};</p>
<p>    //    публикация публичных методов<br />
    return myFunc;<br />
}));<br />

И наш более сложный пример, с несколькими зависимостями и несколькими публичными методами:

<br />
(function (root, factory) {<br />
    if (typeof define === 'function' &amp; define.amd) {<br />
        // AMD<br />
        define(['jquery', 'underscore'], factory);<br />
    } else if (typeof exports === 'object') {<br />
        // Node, CommonJS-like<br />
        module.exports = factory(require('jquery'), require('underscore'));<br />
    } else {<br />
        // Глобальные переменные. root это windows<br />
        root.returnExports = factory(root.jQuery, root._);<br />
    }<br />
}(this, function ($, _) {<br />
    //    methods<br />
    function a(){};    //   приватный метод, так как не возвращается (смотрите ниже)<br />
    function b(){};    //   публичный метод, так как возвращается<br />
    function c(){};    //   публичный метод, так как возвращается</p>
<p>    //    exposed public methods<br />
    return {<br />
        b: b,<br />
        c: c<br />
    }<br />
}));<br />

Это статейка по большей части для личных нужд, оригинал если что тут.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *