Using non-AMD compatible javascript module with require.js?

可紊 提交于 2019-11-30 01:21:39

UPDATE: I have forked an AMD compatible backbone-tastypie called backbone-tastypie-amd.

While sander's solution would work, its a little annoying to do the whole nested require thing every time you want backbone.

backbone-tastypie is what is called a "traditional script". You can solve the issue in 4 ways.

  1. Make backbone-tastypie AMD compatible yourself. You can do this in one of two ways. Option 1 would be to never include backbone directly - only backbone-tastypie. Then modify backbone tastypie to ensure backbone is required.

    var root = this;
    var Backbone = root.Backbone;
    if (!Backbone && (typeof require !== 'undefined')) Backbone = require('backbone').Backbone;
    

    However this isn't very nice because essentially it will start downloading backbone after backbone-tastypie has loaded (synchronous). It also doesn't give requirejs the full understanding of how these modules relate, and thats the point right? So lets wrap backbone-tastypie in a define():

    (function (factory) {
            if (typeof define === 'function' && define.amd) {
                    // AMD. Register as an anonymous module.
                    define(['backbone'], factory);
            } else {
                    // RequireJS isn't being used. Assume backbone is loaded in <script> tags
                    factory(Backbone);
            }
    }(function (Backbone) {
            //Backbone-tastypie contents
    }));
    

    This is by far the best option out of everything in this answer. RequireJS knows about the dependencies and it can resolve them, download them and evaluate them correctly. It's worth noting that Backbone itself loads underscore using option 1 and does not define itself as a module, which is pretty bad. You can get the AMD optimised version of backbone right here. Assuming you are using this AMD version you can now go right ahead and require backbone-tastypie in your app (either by requiring it in a define() or the actual require() function). You dont have to include backbone or underscore either, as those dependencies are resolved by requirejs.

  2. Use the require.js ordering plugin. This forces things to load in order (still asynchronous in some respects as it downloads them whenever, but evaluates in correct order)

    require(["order!backbone.js", "order!backbone-tastypie.js"], function () {
         //Your code
    });
    
  3. Put backbone.js in the priority config. This forces backbone and its dependencies to always load first no matter what.

  4. Append backbone-tastypie to the same file as backbone.js. Every time backbone is loaded, so is backbone tastypie. Hacky? Yes. But this is very similar to the recommended way of using jquery with requireJS (jquery plugins need jquery to be loaded - much like backbone-tastypie needs backbone to be loaded).

The following should work with RequireJS 2.1.0+ assuming you've set up the paths correctly.

require.config({
  shim: {
    'underscore': {
      exports: '_'
    },
    'backbone': {
      deps: ['underscore','jquery'],
      exports: 'Backbone'
    },
    'backbone-tastypie': {
      deps: ['backbone']
    }
  }
);

you can wrap your require with another require the plugin will be loaded first, and afterwards you can do your app.

require(["myCustomTastyPiePlugin.js"], function () {
    //This callback is called after the one script finish loading.

    require(["one.js", "two.js", "three.js"], function () {
        //This callback is called after the three scripts finish loading.

        // all your code goes here...

    });
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!