Caricamento Backbone e Underscore utilizzando RequireJS

Sto cercando di caricare Backbone e Underscore (oltre a jQuery) con RequireJS. Con le ultime versioni di Backbone e Underscore, sembra un po ‘complicato. Per uno, Underscore si registra automaticamente come un modulo, ma Backbone presuppone che Underscore sia disponibile globalmente. Dovrei anche notare che Backbone non sembra registrarsi come un modulo che lo rende un po ‘incoerente con le altre librerie. Questo è il miglior main.js che potrei inventare che funzioni:

require( { paths: { 'backbone': 'libs/backbone/backbone-require', 'templates': '../templates' } }, [ // jQuery registers itself as a module. 'http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js', // Underscore registers itself as a module. 'http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js' ], function() { // These nested require() calls are just due to how Backbone is built. Underscore basically says if require() // is available then it will automatically register an "underscore" module, but it won't register underscore // as a global "_". However, Backbone expects Underscore to be a global variable. To make this work, we require // the Underscore module after it's been defined from within Underscore and set it as a global variable for // Backbone's sake. Hopefully Backbone will soon be able to use the Underscore module directly instead of // assuming it's global. require(['underscore'], function(_) { window._ = _; }); require([ 'order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js', 'order!app' ], function(a, app) { app.initialize(); }) }); 

Dovrei menzionare che, mentre funziona, l’ottimizzatore soffoca su di esso. Io ricevo il seguente:

 Tracing dependencies for: main js: "/home/httpd/aahardy/requirejs/r.js", line 7619: exception from uncaught JavaScript throw: Error: Error: Error evaluating module "undefined" at location "/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js": JavaException: java.io.FileNotFoundException: /home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js (No such file or directory) fileName:/home/httpd/aahardy/phoenix/trunk/ui/js/../../ui-build/js/underscore.js lineNumber: undefined http://requirejs.org/docs/errors.html#defineerror In module tree: main 

C’è un modo migliore di gestirlo? Grazie!

RequireJS 2.X ora si rivolge in modo organico ai moduli non AMD come Backbone e Underscore molto meglio, utilizzando la nuova configurazione shim .

La configurazione dello shim è semplice da usare: (1) uno indica le dipendenze ( deps ), se ce ne sono, (che possono essere dalla configurazione dei paths , o possono essere percorsi validi stessi). (2) (facoltativamente) specifica il nome della variabile globale dal file che stai shimming, che deve essere esportato nelle funzioni del modulo che lo richiedono. (Se non si specificano le esportazioni, sarà necessario utilizzare semplicemente il globale, poiché nulla verrà passato nelle funzioni di richiesta / definizione).

Ecco un semplice esempio di utilizzo di shim per caricare Backbone. Aggiunge anche un’esportazione per il carattere di sottolineatura, anche se non ha alcuna dipendenza.

 require.config({ shim: { underscore: { exports: '_' }, backbone: { deps: ["underscore", "jquery"], exports: "Backbone" } } }); //the "main" function to bootstrap your code require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone) { // or, you could use these deps in a separate module using define }); 

Nota: questo codice semplificato presuppone che jquery, backbone e underscore si trovino in file denominati “jquery.js”, “backbone.js” e “underscore.js” nella stessa directory di questo codice “principale” (che diventa baseURL per richiedere ). Se questo non è il caso, dovrai utilizzare una configurazione dei percorsi .

Personalmente penso con la funzionalità shim incorporata, i vantaggi di non utilizzare una versione biforcuta di Backbone e Underscore superano i benefici dell’uso della fork AMD raccomandata nell’altra risposta popolare, ma in entrambi i casi funziona.

Aggiornamento : dalla versione 1.3.0 supporto di AMD (RequireJS) rimosso da Underscore .

È ansible utilizzare amdjs / Backbone 0.9.1 e il fork di amdjs / Underscore 1.3.1 con supporto AMD di James Burke (il manutentore di RequireJS).

Ulteriori informazioni sul supporto AMD per Underscore e Backbone .

 // main.js using RequireJS 1.0.7 require.config({ paths: { 'jquery': 'libs/jquery/1.7.1/jquery', 'underscore': 'libs/underscore/1.3.1-amdjs/underscore', // AMD support 'backbone': 'libs/backbone/0.9.1-amdjs/backbone', // AMD support 'templates': '../templates' } }); require([ 'domReady', // optional, using RequireJS domReady plugin 'app' ], function(domReady, app){ domReady(function () { app.initialize(); }); }); 

I moduli sono registrati correttamente e non è necessario il plug-in degli ordini:

 // app.js define([ 'jquery', 'underscore', 'backbone' ], function($, _, Backbone){ return { initialize: function(){ // you can use $, _ or Backbone here } }; }); 

Underscore è in realtà opzionale, perché Backbone ora ottiene le sue dipendenze da solo:

 // app.js define(['jquery', 'backbone'], function($, Backbone){ return { initialize: function(){ // you can use $ and Backbone here with // dependencies loaded ie Underscore } }; }); 

Con un po ‘di zucchero AMD potresti anche scriverlo in questo modo:

 define(function(require) { var Backbone = require('backbone'), $ = require('jquery'); return { initialize: function(){ // you can use $ and Backbone here with // dependencies loaded ie Underscore } }; }); 

Riguardo all’errore dell’ottimizzatore: doubleckeck la configurazione della tua build. Presumo che la configurazione del tuo percorso sia distriggersta. Se hai una configurazione di directory simile ai documenti RequireJS puoi usare:

 // app.build.js ({ appDir: "../", baseUrl: "js", dir: "../../ui-build", paths: { 'jquery': 'libs/jquery/1.7.1/jquery', 'underscore': 'libs/underscore/1.3.1-amdjs/underscore', 'backbone': 'libs/backbone/0.9.1-amdjs/backbone', 'templates': '../templates' }, modules: [ { name: "main" } ] }) 

Come riferimento, dalla versione 1.1.1 (~ Feb ’13), Backbone si registra anche come modulo AMD . Funzionerà con requirejs senza la necessità di usare la sua configurazione shim. ( Anche la fork amdjs di James Burke non è stata aggiornata dalla 1.1.0)

Scriverò direttamente, puoi leggere la spiegazione su requirejs.org, potresti usare sotto il codice come uno snippet per il tuo uso quotidiano; (ps io uso yeoman) (dal momento che molte cose sono state aggiornate, la sto postando a febbraio 2014.)

Assicurati di aver incluso lo script nel tuo index.html

    

Quindi, in main.js

 require.config({ shim: { 'backbone': { deps: ['../bower_components/underscore/underscore.js', 'jquery'], exports: 'Backbone' } }, paths: { jquery: '../bower_components/jquery/jquery', backbone: '../bower_components/backbone/backbone' } }); require(['views/app'], function(AppView){ new AppView(); }); 

app.js

 /** * App View */ define(['backbone', 'router'], function(Backbone, MainRouter) { var AppView = Backbone.View.extend({ el: 'body', initialize: function() { App.Router = new MainRouter(); Backbone.history.start(); } }); return AppView; }); 

Spero di essere stato utile.!

Buone notizie, Underscore 1.6.0 ora supporta requirejs define !!!

le versioni al di sotto di questo richiedono shim, o richiedono underscore.js quindi ciecamente sperando che la variabile globale “_” non sia stata distrutta (che per essere onesti è una scommessa giusta)

semplicemente caricarlo

  requirejs.config({ paths: { "underscore": "PATH/underscore-1.6.0.min", } }); 
 require.config({ waitSeconds: 500, paths: { jquery: "libs/jquery/jquery", jqueryCookie: "libs/jquery/jquery.cookie", ..... }, shim: { jqxcore: { export: "$", deps: ["jquery"] }, jqxbuttons: { export: "$", deps: ["jquery", "jqxcore"] } ............ } }); require([  // Load our app module and pass it to our definition function "app" ], function(App) { // The "app" dependency is passed in as "App" // Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function App.initialize(); });