Caché require() de node.js: ¿es posible invalidarlo?

Resuelto William asked hace 12 años • 18 respuestas

De la documentación de node.js:

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

¿Hay alguna manera de invalidar este caché? es decir, para las pruebas unitarias, me gustaría que cada prueba funcione en un objeto nuevo.

William avatar Feb 09 '12 19:02 William
Aceptado

Siempre puedes eliminar de forma segura una entrada en require.cache sin problemas, incluso cuando existen dependencias circulares. Porque cuando elimina, simplemente elimina una referencia al objeto del módulo almacenado en caché, no el objeto del módulo en sí, el objeto del módulo no será GCed porque en el caso de dependencias circulares, todavía hay un objeto que hace referencia a este objeto del módulo.

Supongamos que tienes:

guión a.js:

var b=require('./b.js').b;
exports.a='a from a.js';
exports.b=b;

y script b.js:

var a=require('./a.js').a;
exports.b='b from b.js';
exports.a=a;

Cuando tu lo hagas:

var a=require('./a.js')
var b=require('./b.js')

conseguirás:

> a
{ a: 'a from a.js', b: 'b from b.js' }
> b
{ b: 'b from b.js', a: undefined }

ahora si editas tu b.js:

var a=require('./a.js').a;
exports.b='b from b.js. changed value';
exports.a=a;

y hacer:

delete require.cache[require.resolve('./b.js')]
b=require('./b.js')

conseguirás:

> a
{ a: 'a from a.js', b: 'b from b.js' }
> b
{ b: 'b from b.js. changed value',
  a: 'a from a.js' }

===

Lo anterior es válido si se ejecuta directamente node.js. Sin embargo, si se utilizan herramientas que tienen su propio sistema de almacenamiento en caché de módulos, como jest , la afirmación correcta sería:

jest.resetModules();
kaisa1028 avatar Jul 13 '2012 20:07 kaisa1028

Si siempre desea recargar su módulo, puede agregar esta función:

function requireUncached(module) {
    delete require.cache[require.resolve(module)];
    return require(module);
}

y luego usar requireUncached('./myModule')en lugar de requerir.

luff avatar Apr 17 '2013 12:04 luff