Search code examples
javascriptbackbone.jsrequirejs

Auto defining a custom JS Library in BackboneJS


I've created an JS library to handle all my API calls.

Is there a way to automatically include this in all my views as api without needing to define it at the top of each view?

I've tried adding it to the main js file, but that doesn't seem to carry into the views.


Solution

  • Each Backbone model should handle its API endpoint communications and each module should only require the models it depends on. Otherwise, it goes against the point of making your code more modular.

    That being said, if you just want your API lib to be available everywhere, there are some ways to achieve that and the reason your tries failed is because every module was defined without the API as a dependency, so the order each module is created is not necessarily the one you think.

    You need to ensure that your API module is defined after Backbone, but before everything else. One way I like is to create an overriding module.

    1. Make a new module, (e.g. backbone.extension.js).
    2. Override whatever you want with Backbone.
    3. Use the map config option to point the dependency named backbone of each module to your new module.
    4. Again, with the map option, make your new module points to the original backbone.

    Why use the map option?

    Because I like to have every paths defined correctly inside the require config. I don't want any library paths to be inside one of my custom module. If it changes, I only need to change it in one place.

    How to configure require to override Backbone?

    Make your module, say custom/plugins/backbone.extension.js.

    Then, configure the paths and map them to the right file:

    paths: {
        "backbone": "lib/backbone/backbone",
        "backbone.extension": "custom/plugins/backbone.extension"
    },
    map: {
        "*": {
            // every module should use our custom module.
            "backbone": "backbone.extension",
        },
        // our custom module should use the original backbone
        "backbone.extension": { "backbone": "backbone", },
    },
    

    How to override Backbone?

    Make a module which depends on Backbone and your API library.

    defined(['backbone', 'api'], function(Backbone, api){
        var View = Backbone.View;
        var BackboneExtView = View.extend({
            api: api
        });
        Backbone.View = BackboneExtView;
    
        // or, for this simple case
        Backbone.View.prototype.api = api;
    
        retrun Backbone;
    });
    

    One problem that could arise is if your API module needs Backbone. If it's the case, you could add an exception to the map config so your API requires the original Backbone and it avoids a circular dependency.