node.js - tutorial - node js web app
Comprender los módulos de Node.js: ¿múltiple requiere devolver el mismo objeto? (5)
Tengo una pregunta relacionada con la documentación de node.js en el almacenamiento en caché de módulos :
Los 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 resolvería en el mismo archivo.
Múltiples llamadas a requerir (''foo'') pueden no causar que el código del módulo se ejecute varias veces. Esta es una característica importante. Con él, se pueden devolver objetos "parcialmente hechos", permitiendo así que las dependencias transitivas se carguen incluso cuando causarían ciclos.
¿Qué se entiende por may
?
Quiero saber si require siempre devolverá el mismo objeto. Entonces, en caso de que necesite un módulo A en app.js
y cambie el objeto de exportación dentro de app.js
(el que requiere devoluciones) y después de eso requiera un módulo B en app.js
que requiera el módulo A , siempre obtendré el 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'');
En caso de que el motivo por el que desea 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, así:
var a = require(''./a'');
a = JSON.parse(JSON.stringify(a));
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 real del archivo 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.
De lo que no estoy seguro es de si hay casos de invalidación de la memoria caché que no estén bajo el control o la conciencia del programador, que podrían permitir cargar accidentalmente el mismo archivo de paquete varias veces.
Si tanto app.js
como b.js
residen en el mismo proyecto (y en el mismo directorio), ambos recibirán la misma instancia de A
De la documentación de node.js :
... cada llamada a
require(''foo'')
obtendrá exactamente el mismo objeto devuelto, si se resolvería en el mismo archivo .
La situación es diferente cuando a.js
, b.js
y app.js
están en diferentes módulos npm . Por ejemplo:
[APP] --> [A], [B]
[B] --> [A]
En ese caso, el require(''a'')
en app.js
se resolvería en una copia diferente de a.js
que require(''a'')
en b.js
y, por lo tanto, devolvería una instancia diferente de A
Hay una publicación en el blog que describe este comportamiento con más detalle.
node.js tiene algún tipo de caché implementado que bloquea el nodo de lectura de archivos miles de veces mientras se ejecutan grandes proyectos de servidor.
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 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 hacer 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.
Prueba drex : https://github.com/yuryb/drex
drex está mirando un módulo para las actualizaciones y vuelve a solicitar el módulo limpiamente 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.