108 votes

Comprendre les modules Node.js : plusieurs requêtes renvoient le même objet ?

J'ai une question concernant la documentation de node.js sur la mise en cache des modules :

Les modules sont mis en cache après leur premier chargement. Cela signifie que (entre autres) que chaque exactement le même objet s'il s'agit d'un retour, s'il s'agit d'un retour. fichier.

Plusieurs appels à require('foo') ne peut pas être à l'origine t exécuté plusieurs fois. Il s'agit d'une caractéristique importante. Grâce à elle, le code du module peut être exécuté plusieurs fois, des objets "partiellement réalisés" peuvent être renvoyés, ce qui permet une transitives d'être chargées même lorsqu'elles provoqueraient des cycles.

Qu'entend-on par may ?

Je veux savoir si l'exigence sera siempre renvoient le même objet. Ainsi, si j'ai besoin d'un module A en app.js et modifier l'objet d'exportation dans app.js (celui qui nécessite des retours) et ensuite un module B en app.js qui nécessite elle-même un module A , le ferais-je ? siempre obtenir la version modifiée de cet objet ou un nouvel objet ?

// 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');

79voto

Petr Stodulka Points 8

Si les deux app.js y b.js résider dans le même projet (et dans le même répertoire), ils recevront alors tous les deux la même instance de A . De la documentation node.js :

... chaque appel à require('foo') obtiendra exactement le même objet renvoyée, si elle résolvait dans le même fichier .


La situation est différente lorsque a.js , b.js y app.js sont en différents modules npm . Par exemple :

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

Dans ce cas, le require('a') en app.js se résoudrait à une copie différente de a.js que require('a') en b.js et renvoie donc un instance différente de A . Il existe un article de blog décrivant ce comportement de manière plus détaillée.

6voto

moe Points 38

Node.js dispose d'une sorte de cache qui empêche node de lire des fichiers des milliers de fois lors de l'exécution d'énormes projets de serveur.

Cette cache est répertoriée dans le require.cache objet. Je dois noter que cet objet est en lecture/écriture, ce qui permet de supprimer des fichiers du cache sans tuer le processus.

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

J'ai oublié de répondre à la question. La modification de l'objet exporté n'affecte pas le chargement du module suivant. Cela causerait beaucoup de problèmes... Require renvoie toujours une nouvelle instance de l'objet, sans référence. La modification du fichier et la suppression du cache modifient l'objet exporté.

Après quelques tests, node.js met bien en cache le module.exports. Modifier require.cache[{module}].exports aboutit à un nouvel objet retourné modifié.

3voto

Reg Edit Points 3917

Depuis que la question a été posée, le document a été mis à jour afin de clarifier la raison pour laquelle le terme "peut" a été utilisé à l'origine. Il répond maintenant à la question elle-même en rendant les choses explicites (je souligne pour montrer ce qui a changé) :

Les modules sont mis en cache après leur premier chargement. Cela signifie que (entre autres choses) que chaque appel à require('foo') renverra exactement le même objet retourné, s'il est résolu dans le même fichier. fichier.

A condition que require.cache ne soit pas modifié, m require('foo') se n'est pas à l'origine du code du module t plusieurs fois. Il s'agit d'une caractéristique importante. Grâce à elle, les objets "partiellement réalisés" peuvent être renvoyés. peuvent être renvoyés, ce qui permet de charger des dépendances transitives même lorsqu'elles provoqueraient des cycles.

2voto

coch Points 11

D'après ce que j'ai vu, si le nom du module correspond à un fichier déjà chargé, le module mis en cache sera renvoyé, sinon le nouveau fichier sera chargé séparément.

C'est-à-dire, la mise en cache est basée sur le nom du fichier qui est résolu. En effet, en général, il peut y avoir différentes versions d'un même paquet qui sont installées à différents niveaux de la hiérarchie des fichiers et qui doivent être chargées en conséquence.

Ce dont je ne suis pas sûr, c'est s'il existe des cas d'invalidation du cache que le programmeur ne contrôle pas ou dont il n'est pas conscient et qui pourraient permettre de recharger accidentellement le même fichier paquet plusieurs fois.

1voto

Eugene Beresovksy Points 3852

Si la raison pour laquelle vous souhaitez require(x) de renvoyer un nouvel objet à chaque fois est juste parce que vous modifiez cet objet directement - ce qui est un cas que j'ai rencontré - il suffit de le cloner, de le modifier et de n'utiliser que le clone, comme ceci :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X