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

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

3 мин.

Вступление

На протяжении многих лет экосистема компонентов 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
    }
}));

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

JavaScript | Что такое AMD, CommonJS, и UMD?: 4 комментария

  1. Алёшка

    Просто зашел сюда в пол пятого утра, т.к. не давала покоя мысль, почему в реакте при установке из npm он делится на две папки внутри cjs/umd, теперь я знаю больше *_*

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

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

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


Срок проверки reCAPTCHA истек. Перезагрузите страницу.