RequireJS - при указании идентификатора модуля в define()

В документах RequireJS ( http://requirejs.org/docs/api.html) я не мог понять это предложение.

Вы можете явно назвать модули самостоятельно, но это делает модули менее переносимыми

Мой вопрос

  1. Почему явно именованный модуль делает менее переносимым?
  2. Когда явно нужен модуль именования?

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 (могут быть и некоторые другие крайние случаи, когда он также полезен).

Другие вопросы по тегам