2012-01-16 10 views
73

Tengo una pregunta relacionada con the node.js documentation on module caching:Descripción de los módulos Node.js: ¿múltiple requiere devolver el mismo objeto?

módulos se almacenan en caché después de la primera vez que se cargan. Esto significa (entre otras cosas) que cada llamada a requerir ('foo') obtendrá exactamente el mismo objeto devuelto, si se resuelve en el mismo archivo .

Las llamadas múltiples a requerir ('foo') no pueden causar que el código del módulo sea ejecutado varias veces. Esta es una característica importante. Con él, se pueden devolver los objetos "parcialmente realizados" , permitiendo así que las dependencias transitivas se carguen aunque ocasionen ciclos.

¿Qué se entiende por may?

Quiero saber si es necesario siempre devolver el mismo objeto. Así que en caso requiero un módulo Un en app.js y cambiar las exportaciones oponen a ello en app.js (la que requiere retornos) y después de que requieren un módulo B en app.js que sí requiere módulo Un, se me siempre obtener la versión modificada de ese objeto, o una nueva?

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

Esa frase en los documentos podría haber sido mejor escrita. Me parece que * may not * es lo mismo que * no permitido *, es decir, * múltiples llamadas para requerir ('foo') ** no puede ** hacer que el código del módulo se ejecute varias veces *. –

Respuesta

3

Node.js tiene algún tipo de almacenamiento en caché implementado que bloquea nodo desde la lectura de archivos 1000s de veces durante la ejecución de algunos enormes servidor-proyectos.

Este caché se enumera en el objeto require.cache. Tengo que señalar que este objeto es de lectura/escritura, lo que le da la capacidad de eliminar archivos de la memoria caché sin matar el proceso.

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

Ouh, se olvidó de responder a la pregunta. La modificación del objeto exportado no afecta a la siguiente carga del módulo. Esto causaría muchos problemas ... Exigir siempre devolver una nueva instancia del objeto, sin referencia. La edición del archivo y la eliminación de la memoria caché cambia el objeto exportado

Después de realizar algunas pruebas, node.js almacena en caché el module.exports. La modificación de require.cache[{module}].exports termina en un objeto nuevo, modificado y devuelto.

+1

El código que publiqué realmente funciona. 'b.b' se define con el valor' 2'. Entonces, en este ejemplo, es el mismo objeto. – Xomby

+1

Mismo resultado. Ahora estoy realmente confundido ... – moe

+0

Esa es una característica y en mi opinión bastante útil. La pregunta es si puedo confiar en eso. La documentación dice 'puede', lo que lo hace poco claro. – Xomby

0

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

drex está observando un módulo de actualizaciones y limpiamente re-requiere el módulo después de la actualización. El nuevo código se requiere require() d como si el nuevo código fuera un módulo totalmente diferente, por lo que require.cache no es un problema.

+1

La pregunta era otra, pero drex se ve muy bien para cosas de desarrollo. ¡Gracias! –

1

Por lo que he visto, si el nombre del módulo se resuelve en un archivo previamente cargado, se devolverá el módulo en caché, de lo contrario, el nuevo archivo se cargará por separado.

Es decir, el almacenamiento en caché se basa en el nombre del archivo real que se resuelve. Esto se debe a que, en general, puede haber diferentes versiones del mismo paquete que están instaladas en diferentes niveles de la jerarquía de archivos y que deben cargarse en consecuencia.

Lo que no estoy seguro es si hay casos de invalidación de memoria caché que no están bajo el control o la conciencia del programador, que podrían permitir volver a cargar accidentalmente el mismo archivo de paquete varias veces.

47

Si tanto app.js y b.js residen en el mismo proyecto (y en el mismo directorio) a continuación, ambos de ellos recibirá la misma instancia deA. Desde el node.js documentation:

... cada llamada a require('foo') obtendrá exactamente el mismo objeto devueltos, si se resolvería en el mismo archivo.


La situación es diferente cuando a.js, b.js y app.js son en módulos MNP diferentes. Por ejemplo:

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

En ese caso el require('a') en app.js resolvería a una copia diferente del que a.jsrequire('a') en b.js y, por tanto, devolver una instancia diferente de A. Hay un blog post que describe este comportamiento en más detalle.

+0

usando dos instancias diferentes de A es algo bueno o malo? – NeiL

+0

"y en el mismo directorio". Recibí la misma instancia cuando [B] estaba en una subcarpeta donde vivía [App]. –

+3

¡Vine por algo más y aprendí algo nuevo! TY –

0

En caso de que desee require(x) devolver un objeto nuevo cada vez es solo porque modifica ese objeto directamente, que es un caso en el que me encontré, solo clonelo y modifique y use solo el clon, como este :

var a = require('./a'); 
a = JSON.parse(JSON.stringify(a)); 
Cuestiones relacionadas