2012-01-16 5 views
73

Ho una domanda relativa a the node.js documentation on module caching:Comprensione dei moduli Node.js: più richiede la restituzione dello stesso oggetto?

moduli vengono memorizzate nella cache dopo la prima volta che vengono caricati. Questo significa che (tra le altre cose) otterrà esattamente lo stesso oggetto restituito, se si risolverebbe nello stesso file .

Chiamate multiple per richiedere ('pippo') potrebbe non causare il codice modulo da eseguito più volte. Questa è una caratteristica importante. Con esso è possibile restituire gli oggetti "parzialmente completati", consentendo così il caricamento delle dipendenze transitive anche quando causerebbero cicli.

Cosa si intende con may?

Desidero sapere se il fabbisogno sarà sempre restituire lo stesso oggetto. Quindi nel caso in cui ho bisogno di un modulo Un in app.js e cambiare le esportazioni oggetto all'interno app.js (quello che richiedono i rendimenti) e dopo che richiedono un modulo B in app.js che si richiede modulo A, sarò sempre ottenere la versione modificata di quell'oggetto o una nuova?

// app.js 

var a = require('./a'); 
a.b = 2; 
console.log(a.b); //2 

var b = require('./b'); 
console.log(b.b); //2 

// a.js 

exports.a = 1; 

// b.js 

module.exports = require('./a'); 
+4

Questa frase nei documenti avrebbe potuto essere scritta meglio. Mi sembra che * non * sia uguale a * non consentito a *, cioè * più chiamate da richiedere ('foo') ** non possono ** causare l'esecuzione del codice del modulo più volte *. –

risposta

3

node.js ha una sorta di caching implementato nodo che blocca la lettura da file 1000s di volte durante l'esecuzione di alcuni enormi server-progetti.

Questa cache è elencata nell'oggetto require.cache. Devo notare che questo oggetto è leggibile/scrivibile che dà la possibilità di cancellare i file dalla cache senza uccidere il processo.

http://nodejs.org/docs/latest/api/globals.html#require.cache

Ouh, dimenticato di rispondere alla domanda. La modifica dell'oggetto esportato non influisce sul successivo caricamento del modulo. Ciò causerebbe molti problemi ... Richiedere sempre restituire una nuova istanza dell'oggetto, nessun riferimento. La modifica del file e l'eliminazione della cache cambiano l'oggetto esportato

Dopo aver eseguito alcuni test, node.js memorizza nella cache il modulo.exports. La modifica di require.cache[{module}].exports termina con un nuovo oggetto restituito modificato.

+1

Il codice che ho postato funziona davvero. 'b.b' è definito con il valore' 2'. Quindi in questo esempio è lo stesso oggetto. – Xomby

+1

Stesso risultato. Ora sono davvero confuso ... – moe

+0

Questa è una caratteristica e ai miei occhi abbastanza utile. La domanda è se posso dipendere da questo. La documentazione dice 'may' che non lo rende chiaro. – Xomby

0

provare drex: https://github.com/yuryb/drex

drex sta guardando un modulo per gli aggiornamenti e pulito re-richiede il modulo dopo l'aggiornamento. Il nuovo codice è richiesto() d come se il nuovo codice fosse un modulo completamente diverso, quindi require.cache non è un problema.

+1

La domanda era un'altra, ma drex sembra davvero interessante per gli sviluppi. Grazie! –

1

Per quello che ho visto, se il nome del modulo si risolve in un file precedentemente caricato, il modulo memorizzato nella cache verrà restituito, altrimenti il ​​nuovo file verrà caricato separatamente.

Cioè, il caching si basa sul nome file effettivo che viene risolto. Questo perché, in generale, possono esistere versioni diverse dello stesso pacchetto installate a diversi livelli della gerarchia di file e che devono essere caricate di conseguenza.

Ciò di cui non sono sicuro è che ci siano casi di invalidazione della cache non sotto il controllo o la consapevolezza del programmatore, che potrebbe rendere accidentale ricaricare lo stesso file del pacchetto più volte.

47

Se entrambi app.js e b.js risiedono nello stesso progetto (e nella stessa directory) allora entrambi di loro riceverà la stessa istanza diA. Dal node.js documentation:

... ogni chiamata a require('foo') otterrà esattamente lo stesso oggetto restituito, se risolverebbe allo stesso file.


La situazione è diversa quando a.js, b.js e app.js sono in diversi moduli NPM. Ad esempio:

[APP] --> [A], [B] 
[B] --> [A] 

In tal caso il require('a') in app.js risolverebbe ad una diversa copia di a.js rispetto require('a') in b.js e quindi restituire un diversa istanza di A. C'è un blog post che descrive questo comportamento in modo più dettagliato.

+0

utilizzando due diverse istanze di A è una cosa buona o cattiva? – NeiL

+0

"e nella stessa directory". Ho ricevuto la stessa istanza quando [B] si trovava in una sottocartella di dove viveva [App]. –

+3

Sono venuto per qualcos'altro e ho imparato qualcosa di nuovo! TY –

0

Nel caso in cui il motivo per cui si desidera che require(x) restituisca un oggetto nuovo ogni volta è solo perché si modifica direttamente quell'oggetto - che è un caso in cui mi sono imbattuto - basta clonarlo e modificare e utilizzare solo il clone, come questo :

var a = require('./a'); 
a = JSON.parse(JSON.stringify(a)); 
Problemi correlati