Search code examples
jqueryrequirejsgrunt-contrib-requirejs

RequireJS not loading the right path


I'm trying to retrofit requirejs into a project and I am intermittently getting a "404 Not Found" on files.

Every, roughly, 3 or 4 reloads I get the following errors

GET http://localhost:8080/build/jquery.js 
Uncaught Error: Script error for: jquery

GET http://localhost:8080/build/touchSwipe.js
Uncaught Error: Script error for: touchSwipe

My files looks like this:

config.js

require.config({
    paths: {
        'jquery': 'vendor/jquery',
        'touchSwipe': 'vendor/jquery.touchSwipe.min',
        'scripts': 'scripts/'
    },
    shim: {
        'touchSwipe': {
            deps: ['jquery']
        }
    }
});
require(['main']);

main.js

require(
    ['scripts/menu', 
    .. more js files .. ]);

I use grunt-contrib-requirejs to optimize the files and that all seems to work OK

Gruntfile.js

requirejs: {
    compile: {
        options: {
            baseUrl: "path/to/file/",
            mainConfigFile: "path/to/file/config.js",
            dir: 'path/to/build/',
            modules: [
                {
                    name: 'main'
                },
            ],
            uglify: {
                no_mangle: true
            },
        }
    }
}

...and just to fill in the blanks, my main.hbs file has this script tag

<script data-main="/build/config" src="/js/vendor/require.js"></script>

As I said, this is all working fine until I try to introduce more modules. Modules that I only want to be loaded on certain pages.

I try to do this by adding the following code at the end of the relevant page

<script type="text/javascript">
    require(['scripts/page1']);
</script>

The page1.js file looks like so...

define(['jquery', 'touchSwipe'], function ($j) {
    ...
});

The times when these errors don't appear, the site seems to work fine. Another thing to note is that this only seems to have when I run the code through the Grunt task.

The issue is that the urls, in the errors, are wrong. jQuery should be found at /build/vendor/ rather than /build/, whereas touchSwipe is the path I defined for a library. It looks like a timing issue; the config is being loaded after the new file.


Solution

  • I figured it out

    I need to specify the files in Grunt, under modules, like so

    modules: [
        //First set up the common build layer.
        {
            //module names are relative to baseUrl
            name: 'config',
            include: [
                'jquery',
                'touchSwipe',
                'jquery-ui',
                'modernizr'
            ]
        },
        {
          name: 'scripts/page1',
          exclude: ['config']
        }
    ],
    

    then rather than adding the config file to the script tag, I did this

    require(['./build/config'], function () {  
        require(['scripts/page1']);
    });
    

    and I added

    baseUrl: "build"
    

    to my config file and this seems to have done the trick