Comprendre les modules Node.js: multiple obligatoire renvoie le même object?

J’ai une question liée à la documentation node.js sur la mise en cache des modules :

Les modules sont mis en cache après la première fois qu’ils sont chargés. Cela signifie (entre autres choses) que chaque appel à exiger (‘foo’) obtiendra exactement le même object , s’il était résolu dans le même fichier.

Les appels multiples à demander (‘foo’) peuvent ne pas entraîner l’exécution du code du module plusieurs fois. C’est une caractéristique importante. Avec cela, les objects “partiellement réalisés” peuvent être renvoyés, permettant ainsi de charger les dépendances transitives même lorsqu’elles provoqueraient des cycles.

Que veut-on dire avec may ?

Je veux savoir si le besoin renverra toujours le même object. Donc, au cas où j’aurais besoin d’un module A dans app.js et changerais l’object exports dans app.js (celui qui nécessite des retours) et après avoir besoin d’un module B dans app.js qui requirejs lui-même le module A , version modifiée de cet object, ou un nouveau?

 // app.js var a = require('./a'); ab = 2; console.log(ab); //2 var b = require('./b'); console.log(bb); //2 // a.js exports.a = 1; // b.js module.exports = require('./a'); 

Si à la fois app.js et b.js résident dans le même projet (et dans le même répertoire), les deux recevront la même instance de A De la documentation node.js :

… chaque appel à require('foo') aura exactement le même object retourné, s’il se résolvait au même fichier .


La situation est différente quand a.js , b.js et app.js sont dans des modules npm différents . Par exemple:

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

Dans ce cas, le require('a') dans app.js se résoudrait à une copie différente de a.js que celle a.js require('a') dans b.js et b.js donc une instance différente de A Il y a un article de blog décrivant ce comportement plus en détail.

node.js a mis en place une sorte de mise en cache qui empêche le nœud de lire des fichiers des milliers de fois lors de l’exécution de projets de serveur volumineux.

Ce cache est répertorié dans l’object require.cache . Je dois noter que cet object 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

Ouh, a oublié de répondre à la question. La modification de l’object exporté n’affecte pas le chargement de module suivant. Cela causerait beaucoup de problèmes … Exigez toujours de renvoyer une nouvelle instance de l’object, aucune référence. La modification du fichier et la suppression du cache modifient l’object exporté

Après avoir effectué des tests, node.js met en cache le module.exports. La modification de require.cache[{module}].exports dans un nouvel object retourné modifié.

Pour ce que j’ai vu, si le nom du module est résolu en un fichier pré-chargé, le module en cache sera renvoyé, sinon le nouveau fichier sera chargé séparément.

En d’autres termes , la mise en cache est basée sur le nom de fichier réel qui est résolu. En effet, en général, différentes versions du même package peuvent être installées à différents niveaux de la hiérarchie de fichiers et doivent être chargées en conséquence.

Ce dont je ne suis pas sûr, c’est s’il y a des cas d’invalidation du cache qui ne sont pas sous le contrôle ou la conscience du programmeur, cela pourrait permettre de recharger accidentellement le même fichier de paquet plusieurs fois.

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

drex regarde un module pour les mises à jour et réclame proprement le module après la mise à jour. Le nouveau code est requirejs () d comme si le nouveau code était un module totalement différent, donc require.cache ne pose aucun problème.

Si la raison pour laquelle vous voulez require(x) de renvoyer un nouvel object à chaque fois est simplement parce que vous modifiez directement cet object – ce qui est un cas que j’ai rencontré – il suffit de le cloner et de modifier et utiliser uniquement le clone:

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