Зачем использовать альтернативный requirejs define: define (function (require) {…}
Я видел, как люди используют альтернативное определение "синтаксиса" в require js, чем то, что описано в документации require js или во многих учебниках.
на обычно определяют "синтаксис":
define(['module/first'], function (firstModule) {
//Module code with a dependency on module/first goes here.
});
на альтернативное определение "синтаксис":
<script data-main="app/config" src="assets/js/libs/require.js"></script>
file: config.js:
require.config({
paths: {
jquery: '../assets/js/libs/jquery'
}
});
require(['app']);
: приложение.js:
define(function(require) {
var FirstModule = require('modules/first');
//Module code with a dependency on module/first goes here.
каковы преимущества и недостатки использования этого альтернативного "синтаксис"?
1 ответов
Я думаю, что ваше объяснение немного вводит в заблуждение: в обоих случаях у вас будет верхний уровень require
вызов data-main
атрибут, указывающий файл для запуска процесса требования различных модулей.
так что обычно у вас будет это в вашем HTML:
<script data-main="app/config" src="assets/js/libs/require.js"></script>
затем, в обоих случаях, у вас будет файл app/config
который устанавливает вашу конфигурацию (хотя вы можете сделать это непосредственно в HTML) и, что более важно, вызывает require
on модули:
require.config({
paths: {
jquery: '../assets/js/libs/jquery'
}
});
require(['app']);
теперь, когда мы переходим к определению модулей с зависимостями, эти стили отличаются. В стиле amd вы передаете в модуле имена (пути) как массив, так и функцию, которая принимает одинаковое количество аргументов:
app.js
define(['module/first', 'module/second', 'module/third'], function (firstModule, secondModule, thirdModule) {
// use firstModule, secondModule, thirdModule here
});
в упрощенном синтаксисе CommonJS вы просто передаете require
на define
и после этого требуйте все модули вам inline:
app.js
define(function(require) {
var firstModule = require('modules/first');
var secondModule = require('modules/second');
var thirdModule = require('modules/third');
// use firstModule, secondModule, thirdModule here
}
возвращаясь к вашему первоначальному вопросу, преимущества стиля CommonJS над стилем amd должны быть ясны.
во-первых, с обычным синтаксисом, если требуется много модулей, это очень легко ошибочно назначать модули неправильным именам переменных. Рассмотрим этот распространенный случай:
define(['jquery', 'underscore', 'backbone', 'modules/first', 'modules/second', 'modules/third', 'i18n', 'someOtherModule'], function ($, _, Backbone, first, second, third, I18n, someOtherModule) {
// ...
});
сразу, вы можете увидеть это, когда мы добавим новый модуль к этому списку, мы должны быть очень осторожны, чтобы соответствующий новый аргумент функции появился в нужном месте, иначе мы можем назначить jQuery Backbone
, etc. В некоторых случаях это может создать очень тонкие ошибки, которые трудно отследить.
Теперь рассмотрим синтаксис CommonJS:
define(function(require) {
var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var firstModule = require('modules/first');
var secondModule = require('modules/second');
var thirdModule = require('modules/third');
var I18n = require('i18n');
var someOtherModule = require('someOtherModule');
// ...
}
внимание:
- сопряжение модуля с именем переменной очень ясно.
- порядок операторов require не является важно, поскольку имена переменных спариваются отдельно, а не как сопоставление между массивом и функцией.
- модули не должны быть назначены в первую очередь. Они могут быть назначены в любом месте, пока это до того, как модуль фактически используется.
это всего лишь несколько причин, которые приходят на ум, я уверен, что есть и другие. В принципе, если у вас есть только одна или две зависимости, любой синтаксис будет в порядке. Но если у вас сложная сеть модулей зависимости, синтаксис CommonJS, вероятно, предпочтительнее.
обратите внимание, что в документах RequireJS они упоминают это небольшое предостережение:
не все браузеры дают полезную функцию.прототип.метод toString() результаты. По состоянию на октябрь 2011 года мобильные браузеры PS 3 и более старых Opera не работают. Эти браузеры, скорее всего, нуждаются в оптимизированной сборке модулей для ограничений сети/устройства, поэтому просто сделайте сборку с оптимизатором, который знает, как конвертировать эти файлы в нормализованной форме массива зависимостей, как RequireJS optimizer.
но это не главная проблема:
поскольку количество браузеров, которые не могут поддерживать это сканирование toString (), очень мало, безопасно использовать эти подслащенные формы для всех ваших модулей, особенно если вам нравится выстраивать имена зависимостей с переменными, которые будут содержать их значения модулей.