2012-12-30 17 views
47

Qual è lo scopo della proprietà "exports" nello shim di seguito? È veramente richiesto?RequireJS - Qual è lo scopo della proprietà "exports" nello shim

requirejs.config({ 
    shim: { 
     'backbone': { 
      deps: ['underscore', 'jquery'], 
      exports: 'Backbone' 
     } 
    } 
}); 

chiedo perché sembra ridondante - quando il modulo è incluso in un elenco delle dipendenze, si specificare il nome esportato di nuovo come l'argomento della funzione:

define(['backbone'], function (Backbone) { 
    return Backbone.Model.extend({}); 
}); 

risposta

34

Se l'esempio shim non viene utilizzato nell'esempio, l'oggetto Backbone che si passa come parametro non è definito in quanto Backbone non è compatibile con AMD e non restituisce un oggetto per RequireJS da utilizzare.

define(['backbone'], function (Backbone) { 
    // No shim? Then Backbone here is undefined as it may 
    // load out of order and you'll get an error when 
    // trying to use Model 
    return Backbone.Model.extend({}); 
}); 

Per dare un po 'di contesto userò il codice che il r.js ottimizzatore sputa ma io semplificare per questo esempio. Mi ha aiutato a capire il punto di ciò leggendo ciò che produce l'ottimizzatore.

la spina dorsale spessorato sarebbe un po 'come questo:

// Create self invoked function with the global 'this' 
// passed in. Here it would be window 
define("backbone", (function (global) { 
    // When user requires the 'backbone' module 
    // as a dependency, simply return them window.Backbone 
    // so that properites can be accessed 
    return function() { 
     return global.Backbone; 
    }; 
}(this))); 

Il punto è quello di dare RequireJS qualcosa per tornare di nuovo voi quando si chiede un modulo e lo farà in modo che viene caricato prima di fare così. Nel caso dell'ottimizzatore, incorporerà semplicemente la libreria in anticipo.

+22

Grazie Simon. Non stavo chiedendo perché lo shim è usato, ma perché la proprietà "exports" è necessaria all'interno dello shim? Comunque, la tua risposta mi ha dato un indizio, ad esempio "esportazioni" è usato per identificare il globale che il modulo non AMD introduce. Ora che ho letto di nuovo i documenti, loro dicono: "Una volta caricato, usa il backbone globale come valore del modulo". L'uso di "Backbone" come argomento di funzione fornisce semplicemente un riferimento locale a questo modulo. – Naresh

+1

E solo per aggiungere un altro punto, a volte avere un riferimento locale al globale può essere molto importante, ad esempio, su una pagina in cui possono essere caricate più versioni della stessa libreria. Ad esempio, se stai scrivendo un plugin che dipende da una versione specifica di Knockout, potresti non voler utilizzare la variabile globale 'ko', ma solo il locale che viene passato al callback. –

+0

Almeno Backbone.js 1.3.3 è compatibile con AMD – Legends

1

Shim esporta è per lasciare requirejs sanno come gestire i moduli non AMD. Senza di esso, le dipendenze nel blocco di definizione verranno ancora caricate, mentre il modulo si avvia. Segnala requirejs che ha smesso di caricare la risorsa e che i moduli possono iniziare a usarlo.

Almeno, è così che vedo.

26

Se non si utilizza "esportazione"Backbone, quindi non è possibile ottenere il riferimento locale nel modulo a Backbone (window.Backbone) che è definito in backbone.js.

//without export Backbone 
shim : { 
    'bbn':{ 
     //exports:'Backbone', 
     deps:['underscore'] 
    }, 
    'underscore': { 
     exports: '_' 
    } 
}; 


require(['bbn'], function(localBackbone) { 
    //localBackbone undefined. 
    console.log('localBackbone:,' localBackbone); 
}); 

RequireJs spiega come segue:

//RequireJS will use the shim config to properly load 'backbone' and give a local 
//reference to this module. The global Backbone will still exist on 
//the page too. 
define(['backbone'], function (Backbone) { 
    return Backbone.Model.extend({}); 
}); 

RequireJS useranno shim config per ottenere dorsale globale

function getGlobal(value) { 
     if (!value) { 
      return value; 
     } 
     var g = global; 
     each(value.split('.'), function (part) { 
      g = g[part]; 
     }); 
     return g; 
    } 
+5

La risposta accettata non risponde nemmeno alla domanda! @Ian La risposta di Jiang è migliore! – Mark

2

Si noti inoltre che si potrebbe desiderare di utilizzare effettiva esportazione del plugin in " le esportazioni". Ad esempio,

requirejs.config({ 
    shim: { 
     'jquery.colorize': { 
      deps: ['jquery'], 
      exports: 'jQuery.fn.colorize' 
     }, 
     'jquery.scroll': { 
      deps: ['jquery'], 
      exports: 'jQuery.fn.scroll' 
     }, 
     'backbone.layoutmanager': { 
      deps: ['backbone'] 
      exports: 'Backbone.LayoutManager' 
     }, 
     "jqueryui": { 
      deps: ["jquery"], 
      //This is because jQueryUI plugin exports many things, we would just 
      //have reference to main jQuery object. RequireJS will make sure to 
      //have loaded jqueryui script. 
      exports: "jQuery" 
     }, 
     "jstree": { 
      deps: ["jquery", "jqueryui", "jquery.hotkeys", "jquery.cookie"], 
      exports: "jQuery.fn.jstree" 
     }, 
     "jquery.hotkeys": { 
      deps: ["jquery"], 
      exports: "jQuery" //This plugins don't export object in jQuery.fn 
     }, 
     "jquery.cookie": { 
      deps: ["jquery"], 
      exports: "jQuery" //This plugins don't export object in jQuery.fn 
     } 
    } 
}); 

Più: https://github.com/jrburke/requirejs/wiki/Upgrading-to-RequireJS-2.0#wiki-shim

Problemi correlati