Требовать, чтобы JS игнорировал мою конфигурацию
У меня довольно простая структура каталогов для скриптов:
/js/ <-- located in site root
libs/
jquery-1.10.1.min.js
knockout-2.2.1.js
knockout.mapping.js
models/
model-one.js
model-two.js
...
require.js
config.js
Поскольку механизм сайта использует чистые URL-адреса, я использую абсолютные пути в <script>
:
<script type="text/javascript" data-main="/js/config.js" src="/js/require.js"></script>
RequireJS config:
requirejs.config({
baseUrl: "/js/libs",
paths: {
"jquery": "jquery-1.10.1.min",
"knockout": "knockout-2.2.1",
"komapping": "knockout.mapping"
}
});
Где-то в HTML:
require(["jquery", "knockout", "komapping"], function($, ko, mapping){
// ...
});
Таким образом, проблема заключается в том, что RequireJS полностью игнорирует baseUrl
и paths
, определенные в файле конфигурации. Я получаю ошибку 404 для каждого модуля, требуемого в приведенном ниже коде. Я вижу в консоли браузера, что RequireJS пытается загрузить эти модули из /js/
без каких-либо переводов путей:
404: http://localhost/js/jquery.js
404: http://localhost/js/knockout.js
404: http://localhost/js/komapping.js
Однако после загрузки страницы и появления ошибок я набираю консоль и...
> require.toUrl("jquery")
"/js/libs/jquery-1.10.1.min"
Почему так? Как решить эту проблему?
Это мой первый опыт использования RequireJS, поэтому я чувствую, что пропустил что-то очень простое и очевидное. Помогите, пожалуйста.
Обновление
Только что открыл этот вопрос: Require.js игнорирует baseUrl
Это определенно мой случай. Я вижу на панели "Сеть", что config.js
не полностью загружен до того, как require(...)
запускает собственную загрузку зависимостей.
Но я не хочу размещать свой require(...)
в config, потому что он очень специфичен для вызываемой страницы. Я никогда не замечал такой проблемы с асинхронностью в любом примере, который видел прежде. Как авторы этих примеров поддерживают их работу?
Ответы
Ответ 1
решаемые.
Проблема заключалась в том, что конфигурационный файл, определенный в атрибуте data-main
, загружается асинхронно точно так же, как и другие зависимости. Поэтому мой config.js
случайно не был полностью загружен и выполнен до вызова require
.
Решение описано в официальном RequireJS API: http://requirejs.org/docs/api.html#config
... Кроме того, вы можете определить объект конфигурации как требуемую глобальную переменную перед загрузкой require.js и автоматически использовать значения.
Итак, я только что изменил свой config.js
, чтобы определить глобальный хеш require
с правильной конфигурацией:
var require = {
baseUrl: "/js/libs",
paths: {
"jquery": "jquery-1.10.1.min",
"knockout": "knockout-2.2.1",
"komapping": "knockout.mapping"
}
};
и включил его только до require.js
:
<script type="text/javascript" src="/js/config.js"></script>
<script type="text/javascript" src="/js/require.js"></script>
Этот подход позволяет управлять порядком выполнения script, поэтому config.js
всегда будет загружаться перед следующими вызовами require
.
Теперь все работает отлично.
Ответ 2
Исправлена проблема.
Моя конфигурация загружалась асинхронно, поэтому пути конфигурации не были установлены до вызова оператора require.
В соответствии с документами RequireJS Ссылка здесь, я добавил вызов script в мою конфигурацию перед вызовом require.js. И удалил основной атрибут data.
var require = {
baseUrl: '/js',
paths: {
'jquery': 'vendor/jquery/jquery-2.0.3.min',
'picker': 'vendor/pickadate/picker.min',
'pickadate': 'vendor/pickadate/picker.date.min'
},
shim: {
'jquery': {
exports: '$'
},
'picker': ['jquery'],
'pickadate': {
deps: ['jquery', 'picker'],
exports: 'DatePicker'
}
}
}
Теперь все работает