简体   繁体   中英

require.js text plugin adds “.js” to the file name

I'm trying to work with requirejs and text plugin and I have weird problem.

I have two web servers:

  1. localhost:3000 - act as CDN and has all the static files: js, images, css and templates
  2. localhost:3001 - server - act as REST server and serve only one file, the main.html file

The main.html file loads all the js files from the second server using the following line:

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

For some reason, when using the requirejs text plugin , he adds to the templates ".js" suffix when navigating to localhost:3001

I'm using the following syntax:

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

when I navigate to localhost:3000 it works fine.

Can you think of any reason that the text plugin would have problems serving text files from a remote server (for example, CDN server)?

I've had trouble with the text plugin when working across domains and perhaps your two localhost servers are hitting this too.

In the web inspector I saw that require.js was trying to fetch things like some-content.html.js instead of some-content.html .

Are you running this code in development mode or building into a production set? When you bundle everything up the text plugin shouldn't have this same cross-domain trouble.

Here's the API documentation part that tipped me off (from http://requirejs.org/docs/api.html ):

The baseUrl can be a URL on a different domain as the page that will load require.js. RequireJS script loading works across domains. The only restriction is on text content loaded by text! plugins: those paths should be on the same domain as the page, at least during development. The optimization tool will inline text! plugin resources so after using the optimization tool, you can use resources that reference text! plugin resources from another domain.

Here's an article that helped me work around this for browsers that support CORS :

The documentation of the text plugin gives a hint to the solution: It's possible to configure the plugin in a way that it always fetches remote resources via XHR without appending the .js suffix and loading it via script tag. The simple solution is to always enforce using XHR:

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

Note that the remote server needs to set the correct CORS header and that this could be a security issue. Thus add the necessary checks for trusted urls when using this instead of simply returning true .

I've digged in the code of the text plugin.

I've found out that the text plugin assumes that the developer converted the text template to html since it resides on a different domain.

I've change the code of the text plugin to not assume it.

Someone thinks that I'm doing something wrong?

The original code of the plugin:

            //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);
                });
            }

I've hacked at every solution I've seen posted on the internet aside from running r.js optimizer and compiling my templates into .js file.

A temporary work around is to put your templates in the same directory as your index.html file. This of course doesn't solve the problem but if you are at a standstill like I was, then this will at least get you moving again.

I ran into the same problem and the fix was to make sure the main.js file was loaded from the same domain as the *.htm files. When they differed, require would append the .js to the html files, resulting in 404s.

Such config does not work in current text! plugin. My solution was in overriding useXhr method in 'text' module

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
});

As another alternative way you can use jQuery get method to fetch the content of the template as plain text and then compile it with Handlebars. I came to this solution as a last resort after spending several hours into forums reading about issues with require.js text plugin and CORS. Here's an example :

The template :

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

The js script :

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);

    });

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM