Разница между базой данных и нормальной загрузкой script
При использовании RequireJS, какая разница между включением вашего скрипта в
<script data-main="scripts/main" src="scripts/require.js"></script>
и
<script src="scripts/require.js"></script>
т.е. что изменится атрибут data-main
при загрузке в скрипт? Я прочитал документы по этому вопросу, и другое мне не совсем понятно.
Обычно вы используете сценарий main-data для установки параметров конфигурации, а затем загружаете первый модуль приложения. Примечание: тег script require.js, сгенерированный для вашего основного модуля данных, включает атрибут async. Это означает, что вы не можете предполагать, что загрузка и выполнение вашего основного сценария данных завершится раньше, чем другие сценарии, упомянутые далее на той же странице.
В документации упоминается, что вы обычно будете использовать сценарий main-data для установки параметров конфигурации и загрузки первого модуля приложения - но разве вы не можете сделать это с помощью простого старого тега script
? Есть ли преимущество в конфигурации, загружающей модуль приложения с атрибутом data-main
?
Единственное ли отличается от data-main
асинхронная загрузка? Или есть что-то еще?
Ответы
Ответ 1
data-main
- это еще один способ выполнить начальный вызов require
вашего приложения. Чтобы проиллюстрировать... это:
<script data-main="scripts/main" src="scripts/require.js"></script>
эквивалентно этому:
<script src="scripts/require.js"></script>
<script>require(["scripts/main"])</script>
Две формы являются асинхронными. Это действительно все, что нужно. Соображения о том, сколько точек входа у вас или где будет находиться конфигурация RequireJS, полностью ортогональны использованию data-main
. Иными словами, эти соображения играют определенную роль в использовании data-main
в той же мере, в какой они играют роль при использовании require(["scripts/main"])
.
Часть цитируемой вами документации просто затушевывает вещи, отметив, что script, загруженный с помощью data-main
, создает элемент script
в элементе head
с набором атрибутов async
, потому что это не отличается от загрузки любого script через RequireJS. Каждый script, загруженный RequireJS, будет иметь элемент script
, созданный для него, в head
и имеющий атрибут async
.
Общепринято использовать data-main
для приложений, которые имеют только одну точку входа, и поставить конфигурацию RequireJS в модуль, указанный в data-main
, но это не требуется никакими средствами. Например, это вполне допустимое использование:
<script>
require = {
// RequireJS config here...
};
</script>
<script data-main="scripts/main" src="scripts/require.js"></script>
<script>
require(["foo"], function (foo) {
foo.something();
});
</script>
Конфигурация предоставляется RequireJS, устанавливая require
в глобальном пространстве перед загрузкой RequireJS. (Если require
задано до загрузки RequireJS, в качестве его конфигурации в качестве его значения будет приниматься значение require
.) Помимо запуска приложения при загрузке scripts/main
, этот код также загружает foo
и вызывает на нем метод: два точки входа.
Ответ 2
data-main
предназначен для случаев, когда вы хотите иметь единую точку входа для вашего приложения. Эта единственная строка скрипта загрузит RequireJS вместе с scripts/main.js
и запустит ваше приложение.
Результат
<script data-main="scripts/main" src="scripts/require.js"></script>
означает, что <script async src="scripts/main.js"></script>
добавляется к документу во время выполнения; это скрипт, который будет содержать ваш блок require.config()
и вставит ваш первый скрипт приложения. Если вы не укажете data-main
, тогда вы загружаете только Require и ни один из ваших сценариев приложения, если вы явно не загружаете файл конфигурации и первый модуль.
Как вы думаете, что будет загружать Require, если вы не скажете ему что-либо загружать?
Если вы не используете data-main
, вы должны предоставить точку входа после загрузки Require (это то, как я всегда делал это, без веской причины, кроме той, как я это узнал.) Прочитайте параметры конфигурации чтобы посмотреть, как вы это сделаете.
Я использую этот шаблон в разработке:
<script src="js/lib/require.js"></script>
<script src="js/config.js"></script>
<script>
// same as data-main
require.config({baseUrl : 'js'});
require(['js/main']);
</script>
В качестве единой точки входа содержимое config.js
и последующего вызова require(['js/main'])
будет находиться в любом сценарии, на который ссылается data-main
.
Если вы используете статический оптимизатор для создания производственного пакета, это не имеет значения, поскольку вы просто загружаете пакет.
Ответ 3
data-main - это script, который require.js будет обрабатывать. Как отмечается в документации, в настройках script принято устанавливать параметры конфигурации. Но есть и другие способы сделать это. Во многих случаях это самое простое и эффективное место. Но не всегда.
script, на который указывает основная информация, также отображает зависимости для кода, который определяет файл. Зависимости там, где мясо. Типично, хотя и не обязательно, иметь эту первую загрузку модуля и выполнять то, что в конечном итоге является фактическим приложением.
Добавление в ответ на комментарий:
Есть некоторые концепции, о которых вам нужно знать, что поможет понять этот подход.
Во-первых, нет ни одной (или пары, или даже нескольких) script (s). Этот тип погрузчика предназначен для обработки множества и очень маленьких скриптов. Каждый из них имеет очень конкретную и часто (предпочтительно) единую цель. Вызовите эти скриптовые модули (или единицы).
Любой данный модуль может зависеть от любого количества других модулей, чтобы функционировать. Шаблон AMD позволяет отображать зависимости для каждого модуля в этом определении модуля.
RequireJS будет сортировать, кому нужно то, что и в каком порядке, и не позволять скриптам выполняться до тех пор, пока все модули, за которые они зависят, не будут загружены и готовы.
Так что это совсем не похоже на размещение ссылки script (или нескольких ссылок) на странице, как мы все выросли. Это совсем другой подход к разработке javascript. Как только вы оберните голову и выясните, как разбивать ваш код на скрытые единицы функциональности, он действительно довольно гладкий.
Ответ 4
<script data-main="scripts/main.js" src="scripts/vendor/requirejs/require.js"></script>
src сначала загрузит "scripts/vendor/requirejs/require.js". Затем атрибут data-main выполнит "scripts/main.js".