Tengo esto en el archivo data.js :
module.exports = { data: { value: 42 } }; Lo estoy importando en el archivo test.js :
function load(fileName) { const {data} = require(fileName); data.value += 5; return data; } for (let i = 0; i < 5; i++) console.log(load("data.js")); Cuando ejecuto node test.js , la impresión es:
{ value: 47 } { value: 52 } { value: 57 } { value: 62 } { value: 67 } Esperaba que se imprimiera { value: 42 } en cada iteración, pero entiendo que probablemente data hagan referencia al objeto devuelto desde require(fileName) , por lo que cambiar data.value afecta el contenido de ese objeto.
Pero lo que no entiendo es por qué la instrucción require no se ejecuta "desde cero", es decir, en el archivo de entrada original .
Por supuesto, puedo solucionar esto cambiando data.js en un archivo JSON con el formato adecuado y luego cargando ese archivo usando algo como:
const data = JSON.parse(fs.readFileAsync(data.json)); Pero me gustaría obtener una comprensión más profunda de por qué usar una instrucción require es inapropiado en este caso.
¡Gracias!
Creo que esto sucede debido a la función de caché de la función require() . La función require() almacena en caché el módulo y cada vez que vuelve devuelve la versión almacenada en caché. Cada módulo solo se carga y evalúa la primera vez que se requiere, ya que cualquier llamada posterior de require() simplemente devolverá la versión almacenada en caché . Esto debería quedar claro mirando lo siguiente:
//D:\\backend node\\backend-projects\\test\\test2.js file function load(fileName) { console.log(`cache ${JSON.stringify(require .cache["D:\\backend node\\backend-projects\\test\\test2.js"] .children)}`) //here I print the children property of the require.cache object const {data} = require(fileName); data.value += 5; return data; } for (let i = 0; i < 5; i++) console.log(load("./test.js")); Para la simulación aquí, utilizo un enfoque simple, cada vez que se invoca la función de carga, imprime los datos almacenados en caché para que pueda ver qué sucede cuando se invoca la función require , por lo que esta operación devuelve el siguiente resultado:
cache [] // there is no cached data //because require function is invoked first time, it returns original data { value: 47 } cache [{"id":"D:\\backend node\\backend-projects\\test\\test.js","path":"D:\\backend node\\backend-projects\\test","exports":{"data":{"value":47}},"filename":"D:\\backend node\\backend-projects\\test\\test.js","loaded":true,"children":[],"paths":["D:\\backend node\\backend-projects\\test\\node_modules","D:\\backend node\\backend-projects\\node_modules","D:\\backend node\\node_modules","D:\\node_modules"]}] { value: 52 } cache [{...,"exports":{"data":{"value":52}},..]}] { value: 57 } cache [{...,"exports":{"data":{"value":57}},..]}] { value: 62 } cache [{...,"exports":{"data":{"value":62}},..]}] { value: 67 } Ahora puede ver que cada vez que la función require devuelve la versión en caché del módulo . Si devuelve el módulo original, tenía que ser el valor original, no el valor aumentado.