2011-12-30 41 views
13

Estoy usando require.js para ayudar a organizar mi aplicación basada en Backbone.js.¿Utiliza un módulo javascript no compatible con AMD con require.js?

estoy tratando de averiguar la forma correcta de utilizar una tercera parte Javascript biblioteca que no es compatible con AMD require.js

La biblioteca de preguntas es backbone-tastypie.js. Básicamente lo que hace la biblioteca es parchear algunos de los métodos prototipo de Backbone para proporcionar soporte más simple para el marco REST TasjanPie Django. Lo hace manipulando directamente el objeto Backbone en el espacio de nombres global.

Sin embargo, dado que estoy utilizando Backbone.js como un módulo require.js, no está disponible cuando esta biblioteca intenta acceder a él.

¿Cómo puedo hacer para importar este backbone-tastypie en el ámbito de Backbone?

Respuesta

12

ACTUALIZACIÓN: He bifurcada un compatibles columna vertebral-tastypie AMD llamada backbone-tastypie-amd.

Mientras que la solución de lijadora funcionaría, es un poco molesto para hacer el conjunto anidado requieren que cada vez que quiera columna vertebral.

backbone-tastypie es lo que se llama un "script tradicional". Puedes resolver el problema de 4 maneras.

  1. Hacer backbone-tastypie AMD compatible usted mismo. Puedes hacer esto de una de dos maneras. La opción 1 sería nunca incluir la red troncal directamente, solo backbone-tastypie. Luego, modifique el sabueso de la red troncal para garantizar que se requiera la red troncal.

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

    Sin embargo, esto no es muy agradable porque esencialmente se iniciará la descarga de la columna vertebral después de la espina dorsal-tastypie ha cargado (sincrónica). Tampoco le exige a todos la comprensión completa de cómo se relacionan estos módulos, y ese es el punto correcto? Por lo tanto permite envoltura de columna vertebral-tastypie en una definición():

    (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 
    })); 
    

    Esto es, con mucho, la mejor opción de todo en esta respuesta. RequireJS conoce las dependencias y puede resolverlas, descargarlas y evaluarlas correctamente. Vale la pena señalar que el Backbone en sí carga el guión bajo usando la opción 1 y no se define a sí mismo como un módulo, lo cual es bastante malo. Puede obtener la versión optimizada de AMD de la red troncal right here. Suponiendo que está utilizando esta versión de AMD, ahora puede seguir adelante y requerir backbone-sabrosa en su aplicación (ya sea requiriéndola en una función de definición() o de la función require() real). No es necesario que incluya la red troncal o el subrayado, ya que esas dependencias se resuelven mediante requirejs.

  2. Use the require.js ordering plugin. Esto obliga a cargar las cosas en orden (todavía asíncronos, en algunos aspectos, ya que cada vez que los descarga, sino que evalúa en el orden correcto)

    require(["order!backbone.js", "order!backbone-tastypie.js"], function() { 
        //Your code 
    }); 
    
  3. Backbone.js poner en el priority config. Esto obliga a la red troncal y sus dependencias a cargar siempre primero sin importar qué.

  4. Agregue backbone-tastypie al mismo archivo que backbone.js. Cada vez que se carga la red troncal, también lo hace el sabueso de la red troncal. Hacky? Sí. Pero esto es muy similar a la forma recomendada de usar jquery with requireJS (los plugins de jquery necesitan que se cargue jquery, al igual que backbone-tastypie necesita que se cargue la columna vertebral).

2

puede envolver su requerimiento con otro requiere primero se cargará el complemento, y luego puede hacer su aplicación.

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

    }); 
}); 
+0

Todavía estoy aprendiendo AMD, pero ¿sería posible poner esta declaración de requerimiento anidada en un script separado, y devolver los objetos apropiados combinados como miembros de un objeto compuesto? Si eso funciona, solo necesitarás solicitar un archivo cada vez que necesites ambos. – user4815162342

+0

puede hacerlo así, puede agregarlos en 1 bloque requiere, usando el complemento de orden, para asegurarse de que se cargan en el orden correcto. Luego puede devolverlos como 2 propiedades del 1 nuevo módulo que ha creado. Como en mi ejemplo, podrías devolver el resultado de one.js, two.js y three.js como propiedades de un nuevo módulo. return {one: one, two: two}; – Sander

+0

Gracias, eso es lo que pensé. – user4815162342

9

Lo siguiente debería funcionar con RequireJS 2.1.0+ suponiendo que ha configurado correctamente las rutas.

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