Maison  >  Article  >  interface Web  >  Apprenez-en davantage sur le mécanisme de module de Node et parlez du processus de mise en œuvre du module.

Apprenez-en davantage sur le mécanisme de module de Node et parlez du processus de mise en œuvre du module.

青灯夜游
青灯夜游avant
2022-05-25 21:12:502052parcourir

Cet article vous amènera à comprendre la spécification CommonJs et le mécanisme du module de Node, et à présenter le processus de base de Node implémentant la spécification CommonJs. J'espère qu'il sera utile à tout le monde !

Apprenez-en davantage sur le mécanisme de module de Node et parlez du processus de mise en œuvre du module.

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.

Qu'est-ce que la spécification CommonJs


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 simplement cette spécification. into Il y a 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. require引入其它的模块。

const { add } = require('./add');
const result = add(1 ,2);

模块定义

一个文件就是一个模块,模块里会提供两个变量,分别为module和exports。module为当前模块本身,exports为要导出的内容,同时exports为module的一个属性,即exports为module.exports。其他模块通过require导入的内容即为module.exports的内容。

// add.js
exports.add = (a, b) => {
    return a + b;
}

模块标识

模块标识即为require里面的内容,比如require('./add'),则模块标识为./add

// 缓存的模块示意:
const cachedModule = {
    '/Usr/file/src/add.js': 'add.js编译后的内容',
    'http': 'Node自带的http模块编译后的内容',
    'express': '非路径形式自定义文件模块express编译后的内容'
    // ...
}

Définition du module

Un fichier est un module, et le module fournira deux variables, à savoir le module et les exportations. 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.

/** 
* /Usr/file/index.js;
*/

const { add } = require('add');
const result = add(1, 2);


ID du module

  • L'ID du module est le contenu requis Par exemple, require('./add'), alors l'ID 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 Node
  • Node implémente la spécification CommonJs et ajoute certaines fonctionnalités dont vous avez besoin. Node effectue principalement les trois tâches suivantes pour implémenter la spécification CommonJs :

Analyse du chemin

Positionnement du fichier

Apprenez-en davantage sur le mécanisme de module de Node et parlez du processus de mise en œuvre du module.

Compilation et exécution

Analyse du chemin

Lors de l'exécution de require( ) À ce stade, le paramètre reçu par require est l'identifiant du module, et le nœud utilise l'identifiant du module pour effectuer une analyse du chemin. 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é, le contenu compilé comme valeur, puis d'introduire le module. pour la deuxième fois, il n'est pas nécessaire d'effectuer l'analyse du chemin, la localisation des fichiers, la compilation et l'exécution de ces étapes. Le contenu compilé peut être lu directement à partir du cache.

/** 
* /Usr/file/index.js;
*/

console.log(module.paths);
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 regardez. pour 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/node_modules',
'/Usr/node_modules',
'/node_modules',
]

Dans ce module, nous avons introduit un module d'ajout. Cet ajout n'est pas un module principal ni un chemin. .module de fichier dans le formulaire, puis comment trouver ce module ajouté à ce moment-là.

module a un attribut paths. Le chemin pour trouver le module ajouté est dans l'attribut paths. Nous pouvons taper cet attribut pour voir :

const { add } = require('./add');

Nous pouvons imprimer la valeur des chemins en exécutant node index.js dans le répertoire de fichiers. . La valeur dans paths est un tableau, comme suit : 🎜
// index.js
const { add } = require('./add');
🎜 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. 🎜🎜🎜🎜Positionnement de fichier🎜🎜🎜🎜L'analyse du chemin et le positionnement du fichier sont utilisés ensemble. L'identifiant du fichier peut être sans suffixe, ou un répertoire ou un package peut être trouvé grâce à l'analyse du chemin. À ce stade, il doit être localisé spécifique. les fichiers nécessitent un traitement supplémentaire. 🎜🎜🎜Analyse des extensions de fichiers🎜🎜
const { add } = require('./add');

比如上面这段代码,文件标识符是不带扩展名的,这个时候node会依次查找是否存在.js、.json、.node文件。

目录和包分析

同样是上面这段代码,通过./add查找到的可能不是一个文件,可能是一个目录或者包(通过判断add文件夹下是否有package.json文件来判断是目录还是包)。这个时候文件定位的步骤是这样的:

  • 查看是否有package.json文件
      • 读取package.json里的main字段的值作为文件
    • 没有
      • 寻找目录下的index作为文件(依次查找index.js、index.json、index.node)

如果package.json里没有main字段,那么也会将index作为文件,然后进行扩展名分析找到对应后缀的文件。

模块编译

我们开发中主要遇到的模块为json模块和js模块。

json模块编译

当我们require一个json模块的时候,实际上Node会帮我们使用fs.readFilcSync去读取对应的json文件,得到json字符串,然后调用JSON.parse解析得到json对象,再赋值给module.exports,然后给到require。

js模块编译

当我们require一个js模块的时候,比如

// index.js
const { add } = require('./add');
// add.js
exports.add = (a, b) => {
    return a + b;
}

这个时候发生了什么呢,为什么我们可以直接在模块里使用module、exports、require这些变量。这是因为Node在编译js模块的时候对模块的内容进行了首尾的包装。

比如add.js这个模块,实际编译的时候是会被包装成类似这样的结构:

(function(require, exports, module) {
  exports.add = (a, b) => {
    return a + b;
  }
  return module.exports;
})(require, module.exports, module)

即我们编写的js文件是会被包装成一个函数,我们编写的只是这个函数里的内容,Node后续的包装的过程对我们隐藏了。这个函数支持传入一些参数,其中就包括require、exports和module。

当编译完js文件后,就会执行这个文件,node会将对应的参数传给这个函数然后执行,并且返回module.exports值给到require函数。

以上就是Node实现CommonJs规范的基本流程。

更多node相关知识,请访问:nodejs 教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer