0

I'm trying to minify my requirejs application using grunt it outputs all the files minified and my main.js gets all the used scripts etc ... i run grunt from at the level where the public folder is defined

but when i try to run the optimized main js file it doesn't work and says Backbone is not defined for my 'kinvey' module.. (//da189i1jfloii.cloudfront.net/js/kinvey-backbone-1.1.6.min.js) please help i searched for hours and it doesn't work!

directory layout:

public
 - js
  - libs (all libraries i use)
  - folders / containing modules
  - main.js
  - app.js
 - img ...

main.js:

require.config
(
    {
        paths : {
            'jquery' : 'libs/jquery-1.10.1.min',
            'backbone' : 'libs/backbone.min', // -1.1.2 amd
            'underscore' : 'libs/underscore-1.6.0.min',
            'kinvey' : 'libs/kinvey-backbone-1.1.6.min' // amd
        },
        shim : {
            'underscore' : {
                exports : '_'
            },
            'backbone' : {
                exports : 'Backbone',
                deps : ['jquery','underscore']
            },
            'kinvey' : {
                deps: ['backbone','underscore'],
                //exports: 'Kinvey',
            }
        },
        //deps : ['jquery','underscore']            
    }
);

require
(
    ['backbone', 'kinvey', 'app'],
    function(Backbone, Kinvey, Application)
    {
        'use strict';

        var init = Kinvey.init({ appKey: '...', appSecret : '..'});

        init.then(function(activeUser)
        {       
            if (!activeUser)
            {
                window.location = '/login';
            }
            else
            {
                Application.start();
            }
        }, function(error) {
            alert("Something went wrong.. Please try again.");
            window.location = '/home';
        });     
    }
);

grunt file contains:

                mainConfigFile: "public/js/main.js",
                modules: [
                    {
                        name: 'main',
                     include: ['backbone',
              'kinvey',
              'app']
          }
                ],
                //name: "libs/almond", // node_modules/almond/almond.js
                //wrap: true,
                optimize : 'none',
                dir: "release",

for some reason the output file contains the backbone module and then beneath that the kinvey code.. but for some reason when the kinvey code is run Backbone does not exist, but it needs to because it depends on it (like i did in the config).

It does work fine when not optimized!

Please help me i'm clueless..

Captain Obvious
  • 745
  • 3
  • 17
  • 39

2 Answers2

1

You have notes in your configuration that say "amd" next to your Backbone path and next to your path for Kinvey. AMD-style modules do not need shims. (And a quick check of the code of Backbone 1.1.2 and Kinvey 1.1.6 shows they both call define and thus are AMD-style modules.)

The presence of needless shims very often does not cause immediate problems. So you could have code that works with needless shims when the code is not optimized but fails when it is optimized. Or, to take a completely different example, code that works on Chrome but fails on IE8. And so on and so forth, ...

Edit: Ok, so you point out (correctly) that Kinvey does not list Backbone among its dependencies. That's probably because that version of Kinvey still expects an older version of Backbone, before Backbone was modified for AMD support. You've got multiple options here:

  • Use an old version of Backbone that is not AMD-compliant. You'll need a shim for it. (Kinvey still gets no shim.)

  • Deliberately export Backbone to the global space. You could modify the code after your call to require.config in your main.js file like this:

    require(['backbone'], function (Backbone) {
        window.Backbone = Backbone;
        require(['kinvey', 'app'], function(Kinvey, Application) {
            'use strict';
    
            var init = Kinvey.init({ appKey: '...', appSecret : '..'});
            // Etc. Same code as you originally had.
        });
    });
    

This loads backbone before kinvey is loaded, and exports it to the global space. Kinvey should then be able to find it.

Louis
  • 146,715
  • 28
  • 274
  • 320
  • So you say i need to remove amd from the shim config? – Captain Obvious Mar 03 '14 at 17:47
  • Remove the entries in the `shim` config that are for `backbone` and `kinvey`. – Louis Mar 03 '14 at 17:48
  • I tried deleting them that works fine.. but when i delete the kinvey config.. then it gives errors? Does that mean that it isn't an AMD module? I just looked at the source code of kinvey.. it does export it as a module, but after Backbone has been modified, so it doesn't require backbone at all before modifying it? – Captain Obvious Mar 03 '14 at 17:52
  • I managed to fix it by editing the file, thanks for your efforts thought! (I upvoted) – Captain Obvious Mar 03 '14 at 18:12
  • Ah, well, I did not want to suggest editing the file, seeing as most people (me included) prefer not to patch 3rd party code if they can avoid it. – Louis Mar 03 '14 at 18:14
  • I understand :) i'm gonna try the nested dependency and if it works i'll mark it as an aswer – Captain Obvious Mar 03 '14 at 18:20
0

Same issue here

Trying loading backbone 1.0.0

I had the same problem with backbone 1.1.2

here is an issue tracker that might help

https://github.com/jrburke/requirejs/issues/987

Backbone 1.0.0 seems to have solve the problem for me.

Pascal
  • 2,377
  • 3
  • 25
  • 40
  • The problem is that Kinvey's library is not AMD, you have to manually add the backbone dependency to the require call at the bottom of the librbary, look the answer below – Captain Obvious May 29 '14 at 16:37