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

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

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

какова связь между CommonJS, асинхронным определением модуля (AMD) и RequireJS? Is 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() функция для извлечения зависимостей, an exports переменная для экспорта содержимого модуля и модуля идентификатор (который описывает местоположение рассматриваемого модуля по отношению к этому модулю), который используется для требования зависимостей (источник). CommonJS имеет различные реализации, в том числе узел.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 являются 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"; };
});

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


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

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

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


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

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

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

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

принято от Addy Книга Османи.

// 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:

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

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

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

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

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


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

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 означает, что модуль будет загружен из узла.js. Узел.js будет обрабатывать все от чтения файла системного уровня до обертывания функций в модуль.

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

Я очень смущен CommonJS и AMD?

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