Avant que la spécification CommonJs ne soit proposée, Javascript n'avait pas de système de modules, ce qui signifiait qu'il nous était difficile de développer des applications à grande échelle car l'organisation du code serait plus difficile.
Tout d'abord, CommonJS n'est pas unique à Node. CommonJS est une spécification de module qui définit comment référencer et exporter des modules. Nodejs implémente uniquement cette spécification. La spécification du module CommonJS est principalement divisée en trois parties : la référence du module, la définition du module et l'identification du module. .
Référence du module
La référence du module signifie que nous pouvons introduire d'autres modules via require
.
const { ajouter } = require('./ajouter'); const result = add(1,2);
Module définit
un fichier comme module, et le module fournira deux variables, à savoir module et exports. module est le module actuel lui-même, exports est le contenu à exporter et exports est un attribut du module, c'est-à-dire que exports est module.exports. Le contenu importé par d'autres modules via require est le contenu de module.exports.
// ajouter.js exports.add = (a, b) => { renvoyer a + b ; }
Identification du module
L'identification du module est le contenu de require Par exemple, require('./add')
, alors l'identification du module est ./add
.
Le mécanisme d'importation et d'exportation de modules construit via CommonJS permet aux utilisateurs de créer facilement des applications à grande échelle sans avoir à prendre en compte la pollution variable.
Implémentation du module de nœud
Node implémente la spécification CommonJs et ajoute certaines fonctionnalités dont il a besoin. Node effectue principalement les trois choses suivantes pour implémenter la spécification CommonJs :
Positionnement du fichier
d'analyse de chemin
, compilation et exécution de
l'analyse de chemin
Lorsque require() est exécuté, le paramètre reçu par require est l'identifiant du module et le nœud effectue une analyse de chemin via l'identifiant du module. Le but de l'analyse du chemin est de trouver le chemin où se trouve ce module grâce à l'identifiant du module. Tout d'abord, les modules de nœuds sont divisés en deux catégories, à savoir les modules de base et les modules de fichiers. Le module principal est le module fourni avec le nœud et le module de fichiers est le module écrit par l'utilisateur. Dans le même temps, les modules de fichiers sont divisés en modules de fichiers sous forme de chemins relatifs, en modules de fichiers sous forme de chemins absolus et en modules de fichiers sous forme de non-chemins (tels que express).
Lorsque le nœud trouve un module de fichier, il compilera, exécutera et mettra en cache le module. Le principe général est d'utiliser le chemin complet du module comme clé et le contenu compilé comme valeur. Cela ne sera pas nécessaire lors de l'introduction du module. pour la deuxième fois, effectuez ensuite l'analyse du chemin, la localisation du fichier, la compilation et l'exécution de ces étapes. Le contenu compilé peut être lu directement à partir du cache.
//Diagramme du module de cache : const cachedModule = { '/Usr/file/src/add.js' : 'Contenu compilé de add.js', 'http': 'Contenu compilé du module http fourni avec Node', 'express': 'Contenu compilé du module de fichier personnalisé sans chemin express' //... }
Lorsque vous souhaitez rechercher le module importé par require, l'ordre de recherche du module est de vérifier d'abord si le module est déjà dans le cache. S'il n'est pas dans le cache, vérifiez ensuite le module principal, puis recherchez. le module de fichiers. Parmi eux, les modules de fichiers sous forme de chemins sont plus faciles à trouver. Le chemin complet du fichier peut être obtenu sur la base du chemin relatif ou absolu. Il est relativement difficile de trouver des modules de fichiers personnalisés sous une forme autre que le chemin. Node recherchera le fichier dans le dossier node_modules.
Où se trouve le répertoire node_modules ? Par exemple, le fichier que nous exécutons actuellement est /Usr/file/index.js
/** ; * /Usr/file/index.js; */ const { ajouter } = require('ajouter'); const result = add(1, 2);
Dans ce module, nous avons introduit un module add n'est pas un module principal ni un module de fichier sous la forme d'un chemin. Alors, comment trouver le module add en ce moment.
Le module a un attribut path. Le chemin pour trouver le module ajouté est dans l'attribut paths. Nous pouvons taper cet attribut pour y jeter un oeil :
/**. * /Usr/file/index.js; */ console.log(module.paths);
Nous pouvons imprimer la valeur des chemins en exécutant le nœud index.js dans le répertoire du fichier. La valeur dans paths est un tableau, comme suit :
[ '/Usr/file/node_modules', '/Usr/node_modules', '/node_modules', ]
Autrement dit, Node recherchera séquentiellement dans le répertoire ci-dessus pour voir s'il contient le module d'ajout. Le principe est similaire à la chaîne de prototypes. Commencez par lancer la recherche dans le dossier node_modules dans le répertoire du même niveau que le fichier actuellement exécuté. Si le répertoire node_modules n'est pas trouvé ou n'existe pas, poursuivez la recherche jusqu'au niveau supérieur.
L'analyse du cheminde l'emplacement du fichier
et l'emplacement du fichier peuvent être utilisés ensemble. L'identifiant du fichier peut être sans suffixe, ou un répertoire ou un package peut être trouvé via l'analyse du chemin. Dans ce cas, la localisation du fichier spécifique nécessite un traitement supplémentaire.
Analyse de l'extension de fichier
const { add } = require('./add');
Par exemple, dans le code ci-dessus, l'identifiant de fichier n'a pas d'extension. À ce stade, le nœud recherchera l'existence de .js, .json. , et .node dans l'ordre du document.
L'analyse des répertoires et des packages
est la même que celle du code ci-dessus. Ce qui est trouvé via ./add
n'est peut-être pas un fichier, mais peut être un répertoire ou un package (jugez s'il s'agit d'un répertoire ou d'un package en jugeant s'il existe un package. json dans le dossier d'ajout). À l'heure actuelle, les étapes de positionnement du fichier sont les suivantes :
S'il n'y a pas de champ principal dans package.json, index sera également utilisé comme fichier, puis une analyse d'extension sera effectuée pour trouver le fichier avec le suffixe correspondant .
Compilation de modules
Les principaux modules que nous rencontrons en développement sont les modules json et les modules js.
compilation du module json
Lorsque nous avons besoin d'un module json, Node nous aidera en fait à utiliser fs.readFilcSync pour lire le fichier json correspondant, obtenir la chaîne json, puis appeler JSON.parse pour analyser afin d'obtenir l'objet json, puis l'attribuer à le module exporte, puis donnez-le à require.
js module compilation
Lorsque nous avons besoin d'un module js, tel que
// index.js const { ajouter } = require('./add');
// ajouter.js exports.add = (a, b) => { renvoyer a + b ; }
Que s'est-il passé à ce moment-là ? Pourquoi pouvons-nous utiliser le module variables, exports et require directement dans le module. En effet, Node encapsule le contenu du module en premier et en dernier lors de la compilation du module js.
Par exemple, le module add.js sera empaqueté dans une structure similaire à celle-ci une fois réellement compilé :
(function(require, exports, module) { exports.add = (a, b) => { renvoyer a + b ; } retourner le module.exports ; })(require, module.exports, module)
Autrement dit, le fichier js que nous écrivons sera empaqueté dans une fonction. Ce que nous écrivons n'est que le contenu de cette fonction, et le processus d'empaquetage ultérieur de Node nous est caché. Cette fonction prend en charge la transmission de certains paramètres, notamment require, exports et module.
Une fois le fichier js compilé, le fichier sera exécuté. Node transmettra les paramètres correspondants à cette fonction, puis l'exécutera et renverra la valeur module.exports à la fonction require.
Ce qui précède est le processus de base permettant à Node d'implémenter les spécifications CommonJs.