Require.js bug random Failed to load resource
Asked Answered
A

1

11

My application use require.js, I have a random bug (happens 1 time for 50 reload) Require.js write in the console :

Failed to load resource: the server responded with a status of 404 (Not Found)

Indeed, require.js try to include jquery from a wrong directory... I don't know why, most of the time the application works fine...

My config is pretty simple :

require.config({
  shim: {
    underscore: {
      exports: '_'
    },
    backbone: {
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
    },
    animate_from_to: {
      deps: ['jquery']
    },
    bootstrap: {
      deps: ['jquery']
    },
    zoom: {
      deps: ['jquery']
    },
    shop_util: {
      deps: ['jquery']
    },
    pricer: {
      deps: ['jquery']
    },
    filter: {
      deps: ['jquery']
    },
    paginator: {
      deps: ['jquery']
    },
  },
  paths: {
    bootstrap:        'lib/bootstrap',
    jquery:           'lib/jquery-1.9.1',
    zoom:             'lib/jquery.zoom.min',
    animate_from_to:  'lib/jquery.animate_from_to-1.0.min',
    backbone:         'lib/backbone.min',
    underscore:       'lib/underscore.min',
    text:             'lib/require-text',
    shop_util:  'lib/shop_util',
    pricer:           'lib/pricer',
    filter:           'lib/filter',
    paginator:        'lib/paginator',
  }

});

Thank you

Athabaska answered 10/6, 2013 at 14:17 Comment(5)
What directory is it trying to load?Cleavland
It tries to load from the directory of the "require.config" file. /js/jquery.js instead of /js/lib/jquery.1-9-1.jsAthabaska
Interesting. Do you experience the same behavior in multiple browsers?Cleavland
I don't know, I use Chrome and the bug is so uncommon I can't reproduce itAthabaska
require.config is in the file 'main.js' called by script : <script data-main="js/main" src="js/lib/require.js"></script>Athabaska
M
20

It seems you have another entry point into your application somewhere other than your data-main script (js/main.js). Even if it's a subsequent script in the same page, you cannot depend on your data-main script being completed before the next script runs, since it's loaded with async attribute.

<script data-main="js/main" src="js/lib/require.js"></script>
<!-- foo.js might run before js/main.js !!! -->
<script src="js/foo.js"></script>

You can prove this by adding a console.log statement at the end of js/main.js and one in foo.js (or whatever). Normally you will see the one from js/main.js and then foo.js , but in that 1 out of 50 case you'll see them happen in the other order.

There are several strategies to deal with this:

1 - Do all your app initiation and subsequent require's from your data-main script

Applies to single-page apps, of course. All in one file:

require.config({
  // snip
});
require(['mymodule'], function( mymodule ) {
  // do stuff
});

2 - Use an inline script right after the require.js script tag

Instead of having the above script inside a separate file referenced by data-main, just have a 2nd script tag right below. This is the first example listed in the docs.

Applies mostly to single-page-apps

3 - Load your require config into global variable prior to the require.js script tag

Second example listed in the docs.

<script>
    var require = {
        paths: { // define them}
        shim: { // define them }
    };
</script>
<script src="scripts/require.js"></script>

Applies mostly to single-page-apps

4 - Nest your require calls to load the the config first

This works best for multi-page apps and is the one recommended in the multi-page shim app example

<script src="js/lib/require.js"></script>
<script>
    //Load common code that includes config, then load the app
    //logic for this page. Do the require calls here instead of
    //a separate file so after a build there are only 2 HTTP
    //requests instead of three.
    require(['./js/common'], function (common) {
        //js/common sets the baseUrl to be js/ so
        //can just ask for 'app/main1' here instead
        //of 'js/app/main1'
        require(['app/main1']);
    });
</script>

Related questions here, here, and here

Mogilev answered 11/6, 2013 at 12:52 Comment(4)
Completely right ! I chose the 4nd method, the most "require.js compliant" according to me. Thank you !Athabaska
Isn't require.js supposed to do this anyway, based on the order of files in the array argument?Naoise
@Naoise No, it's not. That's the Async part of AMD -- you don't know in which order the files will be resolved, only that they resolve before calling your function.Mogilev
Thank you! This issue has been bugging me for a long time!Demmy

© 2022 - 2024 — McMap. All rights reserved.