Table des matières
vm模块
module vm
Maison interface Web js tutoriel Une plongée approfondie dans le module VM dans Node.js

Une plongée approfondie dans le module VM dans Node.js

Nov 22, 2021 pm 07:36 PM
node.js

Le module VM est le module principal de NodeJS. Il prend en charge la méthode require et le mécanisme de fonctionnement de NodeJS. Parfois, nous pouvons également utiliser des modèles de VM pour effectuer certaines choses spéciales. Cet article vous donnera une compréhension détaillée du module VM dans Node J'espère qu'il vous sera utile !

Une plongée approfondie dans le module VM dans Node.js

Référence machine virtuelle vm | Site officiel de Node

http://nodejs.cn/api/vm.html

Dans l'article précédent, nous avons mentionné un problème.

Comment une chaîne peut-elle être transformée en JS pour exécution ?

Nous avons présenté deux méthodes en détail, à savoir eval function et new Function.

Nous devons souligner à nouveau ici que les fonctions créées par le constructeur Function ne créent pas de fermetures de l'environnement actuel. Elles sont toujours créées dans l'environnement global, elles ne sont donc accessibles qu'au moment de l'exécution. les variables et leurs propres variables locales ne peuvent pas accéder aux variables dans la portée dans laquelle elles ont été créées par le constructeur Function. Ceci est cohérent avec l'utilisation du evalFunction 构造器创建的函数不会创建当前环境的闭包,它们总是被创建于全局环境,因此在运行时它们只能访问全局变量和自己的局部变量,不能访问它们被 Function 构造器创建时所在的作用域的变量。这一点与使用 eval 执行创建函数的代码不同。

global.a = 100; // 挂在到全局对象global上
var b = 200; // this !== global
new Function("console.log(a)")() // 100
new Function("console.log(b)")() // b is not defined
Copier après la connexion

Function 可以获取全局变量,所以他还是可能会有变量污染的情况出现。Function模块引擎的实现原理 ,后续我会出一篇文章进行单独讲解。

还有一种解决方案,我们在上一次文章中没有进行详细的展开,那就是 vm模块

vm模块

在上述文字中,我一直在强调一个概念,那就是 变量的污染

VM的特点就是不受环境的影响,也可以说他就是一个 沙箱环境 (沙箱模式给模块提供一个环境运行而不影响其它模块和它们私有的沙箱)

const vm = require('vm')
global.a = 100;
// 运行在当前环境中[当前作用域]
vm.runInThisContext('console.log(a)'); // 100
// 运行在新的环境中[其他作用域]
vm.runInNewContext('console.log(a)'); // a is not defined
Copier après la connexion

在这里我们要强调一下,因为 Node.js中全局变量是在多个模块下共享的,所以尽量不要在global中定义属性。 Demo中的定义是为了方便理解。

假设我们在同级目录下有一个文件 1.js ,里面定义了 global.a = 100;。 现在我们引入这个文件

requrie(./1);
console.log(a); // 100
Copier après la connexion

我们可以发现,在当前文件中我们并没有定义变量a,仅仅只是把两个模块文件关联在了一起。这就是我上面提到的,Node中全局变量是在多个模块下共享的。

他的原理是因为在 Node 的环境中,全局中有一个执行上下文。

// 模拟一下Node的全局环境
// vm.runInThisContext在当前全局环境执行,但不会产生新函数
- function(exports, module, require, __dirname, __filename){ // ... }
- vm.runInThisContext ...
// vm.runInNewContext在全局环境之外执行
vm.runInNewContext ...
Copier après la connexion

所以,vm.runInThisContext 可以访问到 global上的全局变量,但是访问不到自定义的变量。而 vm.runInNewContext 访问不到 global,也访问不到自定义变量,他存在于一个全新的执行上下文。

而我们require 就是通过 vm.runInThisContext 实现的。

实现require 主要可以分为以下四步。

  • 读取需要引入的文件。

  • 读取到文件后,将代码封装成一个函数。

  • 通过 vm.runInThisContext Le code qui exécute la fonction de création est différent.

    // 文件a通过module.exports导出一个变量,在文件b中使用require进行接收。
    // a.js
    module.exports = "a"
    // b.js
    let a = require('./a');
    console.log(a); // a
    Copier après la connexion
  • Fonction peut obtenir des variables globales, elle peut donc toujours avoir une pollution variable. Fonction est le principe d'implémentation du
  • moteur de module

    . Je publierai un article pour l'expliquer séparément à l'avenir.

  • Il existe également une solution, que nous n'avons pas développée en détail dans le dernier article, et c'est le module vm.

module vm

Dans le texte ci-dessus, j'ai mis l'accent sur un concept qui est la Pollution des variables. La caractéristique de la VM est qu'elle n'est pas affectée par l'environnement. On peut également dire qu'il s'agit d'un environnement sandbox (le mode Sandbox fournit un environnement permettant aux modules de s'exécuter sans affecter les autres modules et leurs bacs à sable privés. ).

let a = module.exports = "a";
Copier après la connexion

Nous voulons souligner ici que parce que les variables globales dans

Node.js
    sont partagées sous plusieurs modules, essayez donc de ne pas définir de propriétés dans global. Les définitions de la démo sont destinées à faciliter la compréhension.
  • Supposons que nous ayons un fichier 1.js dans le même répertoire, qui définit global.a = 100;. Maintenant que nous introduisons ce fichier

    let a = (function(exports, module, require, __dirname, __filename){
      module.exports = "a";
      return module.exports
    })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
    Copier après la connexion
    Copier après la connexion

    nous pouvons constater que nous ne définissons pas la variable a dans le fichier actuel, nous associons simplement les deux fichiers de module ensemble. C'est ce que j'ai mentionné ci-dessus, les variables globales dans Node sont partagées entre plusieurs modules.

    La raison est que dans l'environnement de

    Node
  • , il existe un contexte d'exécution global.
  • // a.js
    var a = 100;
    module.exports = function(){}
    Copier après la connexion
    Copier après la connexion

    Ainsi, vm.runInThisContext peut accéder aux variables globales sur global, mais ne peut pas accéder aux variables personnalisées. Cependant, vm.runInNewContext ne peut pas accéder à global, ni aux variables personnalisées. Il existe dans un tout nouveau contexte d'exécution. Et notre require est implémenté via vm.runInThisContext.

    🎜L'implémentation de require peut être divisée en quatre étapes suivantes. 🎜🎜🎜🎜Lisez les fichiers qui doivent être importés. 🎜🎜🎜🎜Après avoir lu le fichier, encapsulez le code dans une fonction. 🎜🎜🎜🎜Convertissez-le en syntaxe JS via vm.runInThisContext. 🎜🎜🎜🎜Appel à code. 🎜🎜🎜🎜Supposons que nous ayons maintenant les deux fichiers suivants. Ce sont 🎜a.js🎜 et 🎜b.js🎜🎜
    let a = (function(exports, module, require, __dirname, __filename){
      var a = 100;
      module.exports = function(){};
      return module.exports
    })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
    Copier après la connexion
    Copier après la connexion
    🎜 Nous pouvons analyser la logique de mise en œuvre de l'importation et de l'exportation à travers les quatre étapes ci-dessus. 🎜🎜🎜🎜🎜Lire les fichiers. 🎜🎜🎜Introduisez le contenu du fichier qui doit être importé dans le fichier qui doit être reçu, et il ressemblera à ceci🎜rrreee🎜Mais sous cette forme, Node ne peut pas l'analyser du tout, nous devons donc procéder à la deuxième étape. 🎜🎜🎜🎜🎜Encapsulez le fichier lu dans une fonction. 🎜🎜
    let a = (function(exports, module, require, __dirname, __filename){
      module.exports = "a";
      return module.exports
    })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
    Copier après la connexion
    Copier après la connexion

    封装成函数的原因,我们可以参考下面这个例子。

    假设我们现在传入的不是字符串,而是一个函数。

    // a.js
    var a = 100;
    module.exports = function(){}
    Copier après la connexion
    Copier après la connexion

    这样我们在解析的时候,就会被解析成下面这种格式

    let a = (function(exports, module, require, __dirname, __filename){
      var a = 100;
      module.exports = function(){};
      return module.exports
    })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
    Copier après la connexion
    Copier après la connexion

    我们导出的是 module.exports,所以在模块文件中定义的变量a,也只属于当前这个执行上下文。

    在解析的时候,变量a 会被放到函数中。真正的实现了 作用域分离

  • vm.runInThisContext 解析成可执行的Js代码

    我们处理过的代码会以字符串的形式存在,所以我们需要通过vm.runInThisContext将字符串进行解析。

  • 进行代码调用

    在此之前,我们其实还需要对代码进行调试。

  • 更多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 de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Explication graphique détaillée de la mémoire et du GC du moteur Node V8 Explication graphique détaillée de la mémoire et du GC du moteur Node V8 Mar 29, 2023 pm 06:02 PM

Cet article vous donnera une compréhension approfondie de la mémoire et du garbage collector (GC) du moteur NodeJS V8. J'espère qu'il vous sera utile !

Un article pour parler du contrôle de la mémoire dans Node Un article pour parler du contrôle de la mémoire dans Node Apr 26, 2023 pm 05:37 PM

Le service Node construit sur une base non bloquante et piloté par les événements présente l'avantage d'une faible consommation de mémoire et est très adapté à la gestion de requêtes réseau massives. Dans le contexte de demandes massives, les questions liées au « contrôle de la mémoire » doivent être prises en compte. 1. Le mécanisme de récupération de place du V8 et les limitations de mémoire Js sont contrôlés par la machine de récupération de place

Parlons de la façon de choisir la meilleure image Docker Node.js ? Parlons de la façon de choisir la meilleure image Docker Node.js ? Dec 13, 2022 pm 08:00 PM

Le choix d'une image Docker pour Node peut sembler trivial, mais la taille et les vulnérabilités potentielles de l'image peuvent avoir un impact significatif sur votre processus CI/CD et votre sécurité. Alors, comment choisir la meilleure image Docker Node.js ?

Parlons en profondeur du module File dans Node Parlons en profondeur du module File dans Node Apr 24, 2023 pm 05:49 PM

Le module de fichiers est une encapsulation des opérations de fichiers sous-jacentes, telles que l'ajout de lecture/écriture/ouverture/fermeture/suppression de fichiers, etc. La plus grande caractéristique du module de fichiers est que toutes les méthodes fournissent deux versions de **synchrone** et ** asynchrone**, with Les méthodes avec le suffixe sync sont toutes des méthodes de synchronisation, et celles qui n'en ont pas sont toutes des méthodes hétérogènes.

Node.js 19 est officiellement sorti, parlons de ses 6 fonctionnalités majeures ! Node.js 19 est officiellement sorti, parlons de ses 6 fonctionnalités majeures ! Nov 16, 2022 pm 08:34 PM

Node 19 est officiellement publié. Cet article vous donnera une explication détaillée des 6 fonctionnalités majeures de Node.js 19. J'espère qu'il vous sera utile !

Parlons du mécanisme GC (garbage collection) dans Node.js Parlons du mécanisme GC (garbage collection) dans Node.js Nov 29, 2022 pm 08:44 PM

Comment Node.js fait-il le GC (garbage collection) ? L’article suivant vous guidera à travers cela.

Parlons de la boucle d'événements dans Node Parlons de la boucle d'événements dans Node Apr 11, 2023 pm 07:08 PM

La boucle d'événements est un élément fondamental de Node.js et permet une programmation asynchrone en garantissant que le thread principal n'est pas bloqué. Comprendre la boucle d'événements est crucial pour créer des applications efficaces. L'article suivant vous donnera une compréhension approfondie de la boucle d'événements dans Node. J'espère qu'il vous sera utile !

Parlons de la façon d'utiliser pkg pour empaqueter des projets Node.js dans des fichiers exécutables. Parlons de la façon d'utiliser pkg pour empaqueter des projets Node.js dans des fichiers exécutables. Dec 02, 2022 pm 09:06 PM

Comment empaqueter le fichier exécutable nodejs avec pkg ? L'article suivant vous expliquera comment utiliser pkg pour empaqueter un projet Node dans un fichier exécutable. J'espère qu'il vous sera utile !

See all articles