Отношения между CommonJS, AMD и RequireJS?

Я все еще очень озадачен CommonJS, AMD и RequireJS. Даже после прочтения много.

Я знаю, что CommonJS (ранее ServerJS) - это группа для определения некоторых спецификаций JavaScript (например, модулей), когда язык используется вне браузера. Спецификация модулей CommonJS имеет некоторую реализацию, такую ​​как Node.js или RingoJS, верно?

Какова связь между CommonJS, определением асинхронного модуля (AMD) и RequireJS? Является ли RequireJS реализацией определения модуля CommonJS? Если да, то что такое AMD?

5 ответов

Решение

RequireJS реализует AMD API (источник).

CommonJS - это способ определения модулей с помощью exports объект, который определяет содержимое модуля. Проще говоря, реализация CommonJS может работать так:

// someModule.js
exports.doSomething = function() { return "foo"; };

//otherModule.js
var someModule = require('someModule'); // in the vein of node    
exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };

По сути, CommonJS указывает, что вам нужно иметь require() функция для извлечения зависимостей, exports переменная для экспорта содержимого модуля и идентификатор модуля (который описывает расположение рассматриваемого модуля относительно этого модуля), который используется для запроса зависимостей ( источник). CommonJS имеет различные реализации, включая Node.js, о котором вы упоминали.

CommonJS не был специально разработан для браузеров, поэтому он не очень хорошо вписывается в браузерную среду (уменя действительно нет источника для этого - он просто так говорит везде, включая сайт RequireJS.) По-видимому, это что-то делать с асинхронной загрузкой и т. д.

С другой стороны, RequireJS реализует AMD, которая разработана для соответствия среде браузера ( источник). Судя по всему, AMD начинала как побочный продукт транспортного формата CommonJS и превратилась в собственный API определения модулей. Отсюда сходство между ними. Новая функция в AMD - это define() функция, которая позволяет модулю объявлять свои зависимости перед загрузкой. Например, определение может быть:

define('module/id/string', ['module', 'dependency', 'array'], 
function(module, factory function) {
  return ModuleContents;  
});

Итак, CommonJS и AMD - это API определения модулей JavaScript, которые имеют разные реализации, но оба имеют одинаковое происхождение.

  • AMD больше подходит для браузера, потому что он поддерживает асинхронную загрузку зависимостей модуля.
  • RequireJS является реализацией AMD, при этом стараясь сохранить дух CommonJS (в основном в идентификаторах модулей).

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

define(function(require, exports, module) {
  var someModule = require('someModule'); // in the vein of node    
  exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };
});

Я надеюсь, что это помогает уточнить вещи!

CommonJS - это нечто большее, это проект, который определяет общий API и экосистему для JavaScript. Одной из частей CommonJS является спецификация модуля. Node.js и RingoJS являются средами выполнения JavaScript на стороне сервера, и да, оба они реализуют модули, основанные на спецификации модуля CommonJS.

AMD (Asynchronous Module Definition) - это еще одна спецификация для модулей. RequireJS, пожалуй, самая популярная реализация AMD. Одним из основных отличий от CommonJS является то, что AMD указывает, что модули загружаются асинхронно - это означает, что модули загружаются параллельно, а не блокируют выполнение, ожидая завершения загрузки.

В связи с этим AMD чаще используется в разработке JavaScript на стороне клиента (в браузере), а модули CommonJS обычно используются на стороне сервера. Однако вы можете использовать любую спецификацию модуля в любой среде - например, RequireJS предлагает инструкции по запуску в Node.js, а http://browserify.org/ - это реализация модуля CommonJS, которая может работать в браузере.

Краткий ответ:

CommonJS и AMD - это спецификации (или форматы) того, как модули и их зависимости должны быть объявлены в приложениях javascript.

RequireJS - это библиотека загрузчиков скриптов, совместимая с AMD, еще одним примером является curljs.

CommonJS совместимый:

Взято из книги Адди Османи.

// package/lib is a dependency we require
var lib = require( "package/lib" );

// behavior for our module
function foo(){
    lib.log( "hello world!" );
}

// export (expose) foo to other modules as foobar
exports.foobar = foo;

AMD соответствует:

// package/lib is a dependency we require
define(["package/lib"], function (lib) {

    // behavior for our module
    function foo() {
        lib.log( "hello world!" );
    }

    // export (expose) foo to other modules as foobar
    return {
        foobar: foo
    }
});

Где-то еще модуль можно использовать с:

require(["package/myModule"], function(myModule) {
    myModule.foobar();
});

Немного предыстории:

На самом деле CommonJS - это гораздо больше, чем декларация API, и только часть из них имеет дело с этим. AMD начала как черновую спецификацию для формата модуля в списке CommonJS, но полного согласия не было достигнуто, и дальнейшее развитие формата было перенесено в группу amdjs. Аргументы о том, какой формат лучше, утверждают, что CommonJS пытается охватить более широкий круг вопросов и что он лучше подходит для разработки на стороне сервера, учитывая его синхронный характер, и что AMD лучше подходит для разработки на стороне клиента (браузера), учитывая его асинхронный характер и Дело в том, что он имеет свои корни в реализации декларации модуля Dojo.

Источники:

квотирование

AMD:

  • Один браузер-первый подход
  • Выбор асинхронного поведения и упрощенной обратной совместимости
  • У этого нет никакого понятия Файлового ввода-вывода.
  • Он поддерживает объекты, функции, конструкторы, строки, JSON и многие другие типы модулей.

CommonJS:

  • Один сервер-первый подход
  • Предполагая синхронное поведение
  • Охватите более широкий круг проблем, таких как ввод-вывод, файловая система, обещания и многое другое.
  • Поддерживает развернутые модули, может показаться немного ближе к спецификациям ES.next/Harmony, освобождая вас от оболочки define(), который AMD навязывает.
  • Поддерживайте только объекты как модули.

Вполне нормально организовать модульную программу JavaScript в несколько файлов и вызвать child-modules от main js module,

Дело в том, что JavaScript этого не обеспечивает. Даже сегодня в последних версиях браузера Chrome и FF.

Но есть ли в JavaScript ключевое слово для вызова другого модуля JavaScript?

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


В ES5 (выпущенной в 2009 году) в JavaScript не было ключевых слов, таких как import, include или require.

ES6 экономит время (выпущено в 2015 году), предлагая ключевое слово импорта ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import), но ни один браузер не реализует это.

Если вы используете Babel 6.18.0 и переносите только с опцией ES2015

import myDefault from "my-module";

ты получишь require снова.

"use strict";
var _myModule = require("my-module");
var _myModule2 = _interopRequireDefault(_myModule);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

Это потому что require означает, что модуль будет загружен из Node.js. Node.js будет обрабатывать все, начиная от чтения файлов системного уровня и заканчивая упаковкой функций в модуль.

Потому что в JavaScript функции являются единственными обертками для представления модулей.

Я сильно запутался в CommonJS и AMD?

И CommonJS, и AMD - это всего лишь два разных метода преодоления "дефекта" JavaScript для умной загрузки модулей.

AMD

  • введен в JavaScript для масштабирования проекта JavaScript на несколько файлов
  • в основном используется в браузерных приложениях и библиотеках
  • популярная реализация - RequireJS, Dojo Toolkit

CommonJS:

  • это спецификация для обработки большого количества функций, файлов и модулей большого проекта
  • исходное имя ServerJS, представленное Mozilla в январе 2009 г.
  • переименован в августе 2009 года в CommonJS, чтобы показать более широкую применимость API
  • изначально реализация были сервером, nodejs, настольными библиотеками

пример

файл upper.js

exports.uppercase = str => str.toUpperCase()

файл main.js

const uppercaseModule = require('uppercase.js')
uppercaseModule.uppercase('test')

Резюме

  • AMD - одна из самых древних модульных систем, изначально реализованная библиотекой require.js.
  • CommonJS - модульная система, созданная для сервера Node.js.
  • UMD - еще одна модульная система, предлагаемая как универсальная, совместимая сAMD и CommonJS.

Ресурсы:

Другие вопросы по тегам