Question

I got two small Backbone plugins which look like this:

(function($, _, Backbone) {

var ListView = Backbone.View.extend({
// blablabla
});

Backbone.ListView = ListView;

})($, _, Backbone);

and

(function($, _, Backbone) {

var Repository = Backbone.Model.extend({
// blablabla
});

Backbone.Repository = Repository;

})($, _, Backbone);

I now have set up require.config:

require.config({

    baseUrl: "javascripts",

    shim: {
        "jquery": {
            exports: "$"
        },
        "underscore": {
            exports: "_"
        },
        "backbone": {
            deps: ['jquery', 'underscore'],
            exports: "Backbone"
        },
        "ListView": {
            deps: ['jquery', 'underscore', 'backbone'],
            exports: "Backbone.ListView"
        },
        "Repository": {
            deps: ['jquery', 'underscore', 'backbone'],
            exports: "Backbone.Repository"
        }        

    },

    paths: {
        "jquery": "Vendors/jquery",
        "underscore": "Vendors/underscore",
        "backbone": "Vendors/backbone",
        "ListView": "Extensions/ListView",
        "Repository": "Extensions/Repository"
    }

});

And now we come to the problem. This is how I currently have to handle module dependencies if I want to use both plugins:

require(['jquery', 'underscore', 'ListView', 'Repository'], function($, _, Backbone1, Backbone2) {

    // this is backbone + list view
    console.log(Backbone1);
    // this is backbone + repository
    console.log(Backbone2);       

});

But I would like to have the plugins already registered into backbone:

require(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {

    // this now is backbone + listView + repository
    console.log(Backbone);

});

How do I do this? What do I have to change?

Best regards, bodo

Was it helpful?

Solution

I would suggest first of all to create modules for ListView and Repository to keep them (and hopefully Backbone as well) out of the global namespace, like this:

list_view.js

define(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
  Backbone.ListView = Backbone.View.extend({
    ... ListView code here ...
  }
  return Backbone.ListView
});

repository.js

define(['jquery', 'underscore', 'backbone'], function($, _, Backbone) {
  Backbone.Repository = Backbone.View.extend({
    ... Repository code here ...
  }
  return Backbone.Repository
});

Then you can use require.js' map config to map dependencies to an adapter where you include both modules, and then undo the mapping for the list_view and repository modules themselves to avoid circular dependencies:

requirejs.config({
  map: {
    '*': {
      'backbone': 'backbone-adapter'
    },
    'list_view': {
      'backbone': 'backbone'
    },
    'repository': {
      'backbone': 'backbone'
    },
});

Then create a file backbone-adapter.js to bundle the plugins with Backbone itself:

backbone-adapter.js

define(['backbone', 'list_view', 'repository'], function (Backbone) {
  return Backbone;
});

Then in your modules, when you include 'backbone' as a dependency, requirejs will map that to backbone-adapter, which will in turn include your plugins so that they are available as Backbone.ListView and Backbone.Repository.

I haven't actually tested the code above but I use a similar strategy for bundling vendor modules with my own plugins and it's worked fine for me. (The idea is taken from this discussion.)

OTHER TIPS

I would not do things like that, you're creating a global object containing all your modules, this is not how require.js is intended to be used.

You should explicitly define your dependencies. If you need ListView then add it in the require call, if you need Repository add it in the require call, ...


If you still want to do that, you can define your own Backbone module:

# backbone.js

define(['vendor/backbone', 'ListView', 'Repository'],
  function(Backbone, ListView, Repository) {

    Backbone.ListView = ListView
    Backbone.Repository = Repository

    return Backbone
});

And then your shim config:

paths: {
    ...
    "backbone": "backbone",
    ...
}

(Again, you should really not do it!!)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top