Ответ 1
Рассмотрим первый фрагмент, который находится в стиле CommonJS:
var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');
Эти вызовы являются синхронными вызовами: когда возвращается require
, он возвращает запрошенный модуль. Вызовы CommonJS require
являются синхронными. Существует предложение поддерживать асинхронные формы require
, но, насколько я могу сказать <, он не продвинулся дальше уровня предложения. Node.js использовал require.async
, который был удален. Там package, который его реализует. Использование этого пакета выглядит так же, как использование модулей стиля AMD.
Теперь рассмотрим второй фрагмент кода, который находится в стиле AMD:
require(['jquery','underscore','backbone'],function ($, _, BackBone){
//code goes here
})
Так как RequireJS реализует модульную систему AMD, приведенный выше код работает с RequireJS. Этот вызов require
--- как предлагается по имени Asynchronous Module Definition (AMD) --- асинхронный. Вы не можете полагаться на возвращаемое значение require
, чтобы получить значение модуля. Вместо этого вы должны использовать обратный вызов. Вызов define
работает аналогичным образом, но определяет модуль в дополнение к требуемым модулям.
Теперь, если вы используете RequireJS, он предоставляет средства, которые позволяют использовать любой стиль при определении модулей, чтобы вы могли определить такой модуль:
define(['jquery','underscore','backbone'],function ($, _, BackBone){
//code goes here
});
Или используйте что-то похожее на идиому CommonJS следующим образом:
define(function (require) {
var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');
//code goes here
});
Это упрощает преобразование модуля стиля CommonJS для использования с RequireJS: просто оберните его вызовом define
, как указано выше. Там инструмент поможет преобразовать.
За кулисами RequireJS считывает код обратного вызова во 2-й форме и создает список зависимостей, так что в конце он интерпретируется как:
define(['require', 'jquery','underscore','backbone'], function (require) {
var $ = require('jquery');
var _ = require('underscore');
var BackBone = require('backbone');
//code goes here
})
Может показаться удивительным (учитывая, что AMD является асинхронным), что вызовы require
в обратном вызове синхронны. Это часть поддержки RequireJS для стиля CommonJS. RequireJS поддерживает своего рода синхронный вызов require
, но со следующим оговоркой: если модуль уже определен до вызова синхронного require
, тогда синхронный require
возвращает значение модуля, но в противном случае он немедленно сработает. То есть, он не пытается загрузить модуль. Поскольку RequireJS интерпретирует определение модуля, которое использует стиль CommonJS, как показано выше, как если бы зависимости были фактически перечислены в аргументах define
, то эти модули гарантированно будут загружены к моменту синхронных вызовов до require
.
Помимо возможности использования модулей CommonJS в RequireJS (при условии добавления оболочки), также возможно использовать модули, предназначенные для RequireJS, в среде CommonJS, например Node.js. Например, я использовал node-amd-loader для загрузки модулей, которые я разработал как модули AMD в Node.js.