3
votes

I have a Backbone app that gets errors of Backbone is not defined non-deterministically from different spots in my code that use Backbone. Sometimes it loads first and the site loads, other times it doesn't. I'm using the following as my main.js:

require.config({
  paths: {
    jqueryui: 'libs/jquery/jquery-ui',
    underscore: 'libs/underscore/underscore-min',
    backbone: 'libs/backbone/backbone-min',
    text: 'libs/require/text',
    order: 'libs/require/order',
    searchcollector: 'libs/jquery/searchcollector.plugin',
    guiders: 'libs/jquery/guiders'
  },
  shim: {
    'underscore': {
      exports: '_'
    },
    'backbone': {
      deps: ['underscore'],
      exports: 'Backbone'
    }
  }
});

require([
  'views/app',
  'helpers'
], function(app) {
  var app = window.app = new app();
});

I'm using

<script data-main="/assets/js/main" src="/assets/js/libs/require/require-jquery.js"></script>

in my HTML so jQuery is loaded with the require. I took this advice from this (http://stackoverflow.com/questions/8131265/loading-backbone-and-underscore-using-requirejs) SO thread, but nothing seems to be working. Shouldn't the Shim be loading the Backbone first and then making it globally available? Any help appreciated.

2
Maybe is not related with your problem, but if you use the "shim" config with dependencies (a RequireJS 2.0 feature), you don't need to use the order plugin, see this: github.com/jrburke/requirejs/wiki/Plugins it says that the order plugin only works with RequireJS 1.0Diego
Good catch on the order plugin. As a matter of fact, I've run into the same problem (using order in require2.0) in the past when I switched from 1.0 to 2.0 and didn't know about the changes. I forget if my problem was similar to @eipark 's but I do remember it blowing up my code.jmk2142

2 Answers

3
votes

Not sure if this is the correct answer but I've noticed that you don't list jquery as a Backbone dependency. While Backbone lists Underscore as the only hard dependency, Backbone.View will need jquery or zepto to work.

But why then, does it seem to work some of the time?

It might be that since jQuery is an AMD module, when you load, it sometimes loads first, and other times it doesn't. When it loads before Backbone, it is available and Backbone is happy. Otherwise, perhaps, the bad results you are getting.

Try something like this:

In your path add this:

jquery: 'libs/require/require-jquery'

And in your shim, add this:

'backbone': {
  deps: ['underscore', 'jquery'],
  exports: 'Backbone'
}

Let me know what you get as a result. I've never used the shim feature of requirejs2.0 so I'm curious whether I'm understanding the deeper stuff correctly.

0
votes

In my opinion it's a little bit hacky to load require and jquery in the same file.

And set jquery as a deps for Backbone is false because Underscore need jquery, and it's loaded before Backbone so the correct way is like this

require.config({
  paths: {
     'jquery': 'path to jquery'
    ,'underscore': 'path to underscore'
    ,'backbone': 'path to backbone'
    **other paths...**
  }
  ,shim: {
     jquery: {
      exports: '$'
    }
    ,'underscore': {
      deps: [ 'jquery' ]
      ,exports: '_'
    }
    ,'backbone': {
      deps: [ 'underscore' ]
      ,exports: 'Backbone'
    }
  }
});

Finally your tag script will be

<script data-main="/assets/js/main" src="/assets/js/libs/require.js">
</script>

Then you just have to call lib you need like this

define( [ 'jquery', 'underscore', 'backbone' ],
  function( $, _, Backbone )
  {
    // stuff
  } );

And for a model you maybe don't need jquery and underscore so just calling Backbone will work

define( [ 'backbone' ],
  function( Backbone )
  {
    // Backbone.extend ?
  } );