如何在使用require.js时使用非AMD兼容的javascript模块?

14

我正在使用require.js来帮助组织基于Backbone.js的应用程序。

我正试图找出正确的方法来使用一个与require.js不兼容的第三方JavaScript库。

有问题的库是backbone-tastypie.js。该库的基本作用是monkeypatch一些Backbone原型方法,以提供更简单的TastyPie Django REST框架支持。它通过直接操作全局命名空间中的Backbone对象来实现这一点。

但是,由于我将Backbone.js作为require.js模块使用,因此当此库尝试访问它时,它是不可用的。

我该如何在Backbone范围内导入此backbone-tastypie?

3个回答

12

更新:我已经复制了一个兼容AMD的backbone-tastypie,称为backbone-tastypie-amd。

sander的解决方案虽然可行,但每次想要使用backbone时都要进行整个嵌套式require有点烦人。

backbone-tastypie被称为“传统脚本”。你可以通过4种方法解决这个问题。

  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).


9
以下内容假设您已正确设置路径,并且使用RequireJS 2.1.0+版本,应该可以正常工作。
require.config({
  shim: {
    'underscore': {
      exports: '_'
    },
    'backbone': {
      deps: ['underscore','jquery'],
      exports: 'Backbone'
    },
    'backbone-tastypie': {
      deps: ['backbone']
    }
  }
);

2
您可以使用另一个 require 将其包装起来,插件将首先被加载,然后您就可以运行您的应用程序。
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...

    });
});

我还在学习AMD,但是是否可以将这个嵌套的require语句放在一个单独的脚本中,并将适当的对象作为组合对象的成员返回?如果可以的话,那么每当您需要两者时,只需要要求一个文件即可。 - user4815162342
你可以这样做,将它们添加到一个 require 块中,并使用 order 插件确保它们按正确的顺序加载。然后,你可以将它们作为一个新模块的两个属性返回。就像我的例子一样,你可以将 one.js、two.js 和 three.js 的结果作为新模块的属性返回。return {one: one, two: two}; - Sander
谢谢,这正是我所想的。 - user4815162342
使用Require时不需要.js扩展名。 - danwellman
对于初学者来说,使用它更容易理解它的实际作用。 - Sander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接