Связь между CommonJS, AMD и RequireJS?

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

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

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

+658
13 мая '13 в 11:56
источник поделиться
5 ответов

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

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 для экспорта содержимого модуля и идентификатор модуля (который описывает расположение соответствующего модуля относительно этого модуля) для использования зависимостей (source). CommonJS имеет различные реализации, в том числе Node.js, которые вы упомянули.

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

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

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

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

  • 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"; };
});

Надеюсь, это поможет прояснить ситуацию!

+631
13 мая '13 в 13:14
источник

Связанные вопросы


Похожие вопросы

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

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

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

+174
13 мая '13 в 13:06
источник

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

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

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

Совместимость с CommonJS:

Взято из Addy Osmani book.

// 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 group. Аргументы вокруг какого формата лучше утверждают, что CommonJS пытается охватить более широкий круг проблем и что он лучше подходит для развития на стороне сервера с учетом его синхронного характера и что AMD лучше подходит для развития клиентской стороны (браузера), учитывая его асинхронный характер и факт, что он имеет свои корни в реализации декларации модуля Dojo.

Источники:

+162
29 дек. '13 в 23:05
источник

Цитата

AMD

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

CommonJS

  • Один подход к серверу
  • Предполагая синхронное поведение
  • Покройте более широкий набор проблем, таких как ввод-вывод, файловая система, Promises и многое другое.
  • Поддерживает развернутые модули, он может чувствовать себя немного ближе к спецификациям ES.next/Harmony, освобождая вас от обертки define(), которая AMD обеспечивает,
  • Поддерживать объекты только как модули.
+16
29 июл. '15 в 10:36
источник

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

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

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

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


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

ES6 сохраняет день (выпущенный в 2015 году), предлагая ключевое слово import (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 для загрузки модулей smart.

+7
30 окт. '16 в 23:50
источник

Посмотрите другие вопросы по меткам или Задайте вопрос