Текстовый плагин require.js добавляет ".js" к имени файла

Я пытаюсь работать с requirejs и текстовым плагином, и у меня есть странная проблема.

У меня есть два веб-сервера:

  • localhost: 3000 - действует как CDN и имеет все статические файлы: js, images, css и templates
  • localhost: 3001 - сервер - действует как сервер REST и обслуживает только один файл, файл main.html

Файл main.html загружает все файлы js со второго сервера, используя следующую строку:

<script data-main="http://localhost:3000/js/main" 
        src="http://localhost:3000/lib/require-jquery.js"></script>

По какой-то причине при использовании текстового плагина requirejs он добавляет к суффиксу шаблонов ".js" при навигации по localhost: 3001

Я использую следующий синтаксис:

define ['jquery','backbone','underscore','models/model','text!templates/main.html', 
        'views/navigation', 'views/player', 'views/content', 'views/header']

когда я перехожу к localhost: 3000, он отлично работает.

Можете ли вы подумать о какой-либо причине, что текстовый плагин будет иметь проблемы с обслуживанием текстовых файлов с удаленного сервера (например, сервера CDN)?

Ответы

Ответ 1

Я выкопал в коде текстового плагина.

Я выяснил, что текстовый плагин предполагает, что разработчик преобразовал текстовый шаблон в html, поскольку он находится в другом домене.

Я изменил код текстового плагина, чтобы не предполагать его.

Кто-то думает, что я делаю что-то неправильно?

Исходный код плагина:

            //Load the text. Use XHR if possible and in a browser.
            if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
                text.get(url, function (content) {
                    text.finishLoad(name, parsed.strip, content, onLoad, config);
                });
            } else {
                //Need to fetch the resource across domains. Assume
                //the resource has been optimized into a JS module. Fetch
                //by the module name + extension, but do not include the
                //!strip part to avoid file system issues.
                req([nonStripName], function (content) {
                    text.finishLoad(parsed.moduleName + '.' + parsed.ext,
                                    parsed.strip, content, onLoad, config);
                });
            }

Ответ 2

У меня возникли проблемы с текстовым плагином при работе в разных доменах, и, возможно, ваши два сервера localhost тоже попали в это.

В веб-инспекторе я увидел, что require.js пытался получить такие вещи, как some-content.html.js вместо some-content.html.

Вы используете этот код в режиме разработки или встраиваете в производственный комплект? Когда вы связываете все, текстовый плагин не должен иметь такую ​​же проблему между доменами.

Здесь часть документации API, которая меня опрокинула (от http://requirejs.org/docs/api.html):

BaseUrl может быть URL-адресом в другом домене в качестве страницы, которая будет load require.js. RequireJS script загрузка осуществляется через домены. The только ограничение на текстовое содержимое, загруженное текстом! плагины: те пути должны быть в том же домене, что и страница, по крайней мере во время разработка. Инструмент оптимизации будет встроенным текстом! плагин ресурсов, поэтому после использования инструмента оптимизации вы можете использовать ресурсы этот справочный текст! ресурсы плагинов из другого домена.

Здесь статья, которая помогла мне обойти это для браузеров, поддерживающих CORS:

Ответ 3

Документация текстового плагина дает подсказку: возможно настроить плагин таким образом, чтобы он всегда извлекал удаленные ресурсы через XHR, не добавляя .js и загрузить его с помощью тега script. Простое решение - всегда использовать XHR:

requirejs.config({
   config: {
      text: {
         useXhr: function (url, protocol, hostname, port) {
            return true;
         }
      }
   }
});

Обратите внимание, что удаленному серверу необходимо установить правильный заголовок CORS и что это может быть проблемой безопасности. Таким образом, добавьте необходимые проверки для доверенных URL-адресов при использовании этого вместо простого возврата true.

Ответ 4

Я взломал каждое решение, которое я видел в Интернете, помимо запуска оптимизатора r.js и компиляции моих шаблонов в .js файл.

Временная работа заключается в том, чтобы поместить ваши шаблоны в тот же каталог, что и ваш файл index.html. Это, конечно, не решает проблему, но если вы находитесь в таком состоянии, как я, то это по крайней мере заставит вас двигаться снова.

Ответ 5

Я столкнулся с той же проблемой, и было исправлено, что файл main.js был загружен из того же домена, что и файлы *.htm. Когда они отличаются друг от друга, потребовалось бы добавить .js в файлы html, в результате получится 404s.

Ответ 6

Такая конфигурация не работает в текущем тексте! плагин. Мое решение заключалось в переопределении метода useXhr в модуле "текст"

require(["text"], function (text)
{   if( location.port == '4502' || location.port == '4503' )// AEM env-t
        text.useXhr = function(){ return true; }
    require(["loader/widget/WidgetLoader"]); // dependent on HTML templates by text! plugin
});

Ответ 7

В качестве другого альтернативного способа вы можете использовать метод get jQuery, чтобы извлечь содержимое шаблона в виде простого текста, а затем скомпилировать его с помощью Handlebars. Я пришел к этому решению как к последнему средству, потратив несколько часов на форумах, читающих о проблемах с текстовым плагином require.js и CORS. Вот пример:

Шаблон:

<span class="badge badge-pill badge-danger">Default</span>
<div class="entry">
    <h1>{{title}}</h1>
    <div class="body">
        {{body}}
    </div>
</div>

JS-скрипт:

var deps = [
    'jquery',
    'handlebars',
];

require(deps, function($, handlebars){

    var template = 'https://your_site/raw.templates/basic.handlebars';

    $.get(template, function( data, textStatus, jqxhr ) {
        var Handlebars = handlebars;

        var basicTemplate = Handlebars.compile(data);

        var context = {title: "My New Post", body: "This is my first post!"};

        var html = basicTemplate(context);

        var grid = document.createElement('div');
        grid.setAttribute('id', 'itemsGrid');
        grid.innerHTML = html;
        document.body.appendChild(grid);

    });

});