RequireJS - при указании идентификатора модуля в define()
В документах RequireJS ( http://requirejs.org/docs/api.html) я не мог понять это предложение.
Вы можете явно назвать модули самостоятельно, но это делает модули менее переносимыми
Мой вопрос
- Почему явно именованный модуль делает менее переносимым?
- Когда явно нужен модуль именования?
2 ответа
Почему явно именованный модуль делает менее переносимым?
Если вы не дадите модулю имя в явном виде, RequireJS может назвать его по своему усмотрению, что дает вам больше свободы в отношении имени, которое вы можете использовать для ссылки на модуль. Допустим, у вас есть модуль файла bar.js
, Вы можете указать RequireJS этот путь:
paths: {
"foo": "bar"
}
И вы можете загрузить модуль под названием "foo"
, Если вы дали имя модулю в define
позвоните, тогда вы будете вынуждены использовать это имя. Отличный пример этой проблемы с jQuery. Случилось так, что разработчики jQuery решили (без какой-либо веской причины, которую я могу различить) жестко закодировать имя модуля "jquery"
в коде jQuery. Время от времени кто-то приходит на SO, жалуясь, что их код не будет работать, и их paths
имеет это:
paths: {
jQuery: "path/to/jquery"
}
Это не работает из-за жестко закодированного имени. paths
Конфигурация должна использовать имя "jquery"
, все строчные. (A map
Конфигурация может быть использована для сопоставления "jquery"
в "jQuery"
.)
Когда явно нужен модуль именования?
Это необходимо, когда нет другого способа назвать модуль. Хороший пример r.js
когда он объединяет несколько модулей вместе в один файл. Если модули не были названы во время конкатенации, не было бы никакого способа обратиться к ним. Так r.js
добавляет явные имена ко всем модулям, которые он объединяет (если вы не скажете ему не делать этого или если модуль уже не назван).
Иногда я использую явное именование для того, что я называю "клеем" или "служебными" модулями. Например, предположим, что jQuery уже загружен через script
элемент перед RequireJS, но я также хочу, чтобы мои модули RequireJS могли требовать модуль jquery
получить доступ к jQuery, а не полагаться на глобальный $
, Если я когда-нибудь захочу запустить свой код в контексте, где нет глобального jQuery, то мне не нужно изменять его для этой ситуации. У меня мог бы быть главный файл как это:
define('jquery', function () {
return $;
});
require.config({ ... });
jquery
Модуль существует только для удовлетворения модулей, которые нуждаются в jQuery. Ничего не получится, если поместить его в отдельный файл, и для правильного обращения к нему необходимо дать явное имя.
Вот почему названные модули менее переносимы из Sitepen "AMD, The Definite Source":
AMD также является "анонимной", что означает, что модуль не должен жестко кодировать какие-либо ссылки на свой собственный путь, имя модуля зависит исключительно от имени файла и пути к каталогу, что значительно облегчает любые попытки рефакторинга.
http://www.sitepen.com/blog/2012/06/25/amd-the-definitive-source/
А из книги Эдди Османи "Написание модульного JavaScript":
При работе с анонимными модулями идея идентификации модуля является СУХОЙ, что делает ее тривиальной, чтобы избежать дублирования имен файлов и кода. Поскольку код более переносим, его можно легко перемещать в другие места (или вокруг файловой системы) без необходимости изменять сам код или изменять его идентификатор. Module_id эквивалентен путям к папкам в простых пакетах и когда не используется в пакетах. Разработчики также могут запускать один и тот же код в нескольких средах, просто используя оптимизатор AMD, который работает с средой CommonJS, такой как r.js.
http://addyosmani.com/writing-modular-js/
Зачем нужен явно названный модуль, опять же из "Написание модульного javascript" Адди Османи:
Module_id является необязательным аргументом, который обычно требуется только при использовании инструментов конкатенации не-AMD (могут быть и некоторые другие крайние случаи, когда он также полезен).