Load requireJS модуль встроен в тело HTML?
Я интегрирую RequireJS в CMS, поэтому я разместил это в нижней части шаблона моей страницы:
<html>
<body>
{Placeholder1}
<script src="scripts/require.js" data-main="scripts/main"></script>
{Placeholder2}
</body>
</html>
Затем на каждой странице я хотел бы создать функцию, которая использует RequireJS. Поэтому я попытался разместить это в нижней части страницы:
<html>
<body>
<h1>Home</h1>
<div class="slider">Slider content</div>
<script src="scripts/require.js" data-main="scripts/main"></script>
<script type="text/javascript">
require([
'jquery',
'utils',
'slider'
], function ($, utils, slider) {
slider.start();
});
</script>
</body>
</html>
Но я получаю 404 на jquery, utils и слайдерах js файлов. Похоже, что я не читаю мои настройки main.js, которые у меня есть:
require.config({
paths: {
jquery: 'libs/jquery-1.8.1.min',
utils: 'libs/utils',
slider: 'libs/jquery.slider.min'
},
shim: {
slider: ['jquery']
}
});
require([ 'utils' ], function (utils) {
utils.init();
});
Я попытался загрузить RequireJS и main в заголовке страницы, но таким образом получил несогласованные результаты. Иногда jquery, utils и слайдер загружаются вовремя, а иногда и нет. Это похоже на то, что встроенный "запрос" в нижней части страницы не знает о главном требовании на странице или правилах зависимостей, но моя точка останова попадает в main.js, поэтому я знаю, что она вызывается. Это потому, что main.js загружается асинхронно, но мой встроенный блок "require" в нижней части страницы загружается на странице рендеринга? Как мне обойти это?
Я использовал RequireJS успешно, но без CMS. Я всегда использовал "define", и модули всегда назывались асинхронно, но никогда не приходилось ссылаться на функцию RequireJS inline следующим образом. Любые идеи относительно правильного пути для этого?
Ответы
Ответ 1
Важно то, что параметры конфигурации устанавливаются перед запросом модулей. Как вы правильно определили, существуют условия гонки, которые означают, что параметры конфигурации в вашем main.js
не загружаются вовремя. Простейшим способом было бы установить параметры конфигурации внутри строки до загрузки require.js
script.
<script>
var require = {
baseUrl: <?= $someVar ?>,
paths: {
// etc
}
}
</script>
<script src="scripts/require.js" data-main="scripts/main"></script>
Далее по странице:
<script>
require([
'jquery',
'utils',
'slider'
], function ($, utils, slider) {
slider.start();
});
</script>
См. также Как RequireJS работает с несколькими страницами и частичными представлениями?
Ответ 2
Похоже, что происходит то, что main.js загружается асинхронно, а встроенный запрос вызывается сразу. Вот почему есть непоследовательные результаты. Решение состоит в том, чтобы НЕ использовать атрибут data-main и вызывать файл main.js с помощью тега script под тегом require.js script.
Вы все равно можете определить baseUrl из загруженного файла main.js, выполнив это:
//DETERMINE BASE URL FROM CURRENT SCRIPT PATH
var scripts = document.getElementsByTagName("script");
var src = scripts[scripts.length-1].src;
var baseUrl = src.substring(src.indexOf(document.location.pathname), src.lastIndexOf('/'));
//CONFIGURE LIBRARIES AND DEPENDENCIES VIA REQUIREJS
require.config({
baseUrl: baseUrl,
....