A deep dive into the VM module in Node.js

青灯夜游
Release: 2021-11-22 19:36:18
forward
3376 people have browsed it

The VM module is the core module in NodeJS, which supports the require method and the operating mechanism of NodeJS. Sometimes we may also use VM templates to do some special things. This article will give you a detailed understanding of the VM module inNode. I hope it will be helpful to you!

A deep dive into the VM module in Node.js

Reference vm virtual machine | Node official website

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

In the previous article, we mentioned a problem.

How can a string be turned into JS for execution?

We introduced two methods in detail, namelyeval functionandnew Function.

Here we need to emphasize again that functions created by theFunctionconstructor do not create closures of the current environment. They are always created in the global environment, so they are created at runtime. You can only access global variables and your own local variables, not variables in the scope in which they were created by theFunctionconstructor. This is different from usingevalto execute code that creates a function.

global.a = 100; // 挂在到全局对象global上 var b = 200; // this !== global new Function("console.log(a)")() // 100 new Function("console.log(b)")() // b is not defined
Copy after login

Functioncan obtain global variables, so it may still have variable pollution.Functionis the implementation principle ofmodule engine. I will publish an article to explain it separately in the future.

There is another solution, which we did not expand on in detail in the last article, that isvmmodule.

vm module

In the above text, I have been emphasizing a concept, which is the pollution ofvariables.

The characteristic of VM is that it is not affected by the environment. It can also be said that it is asandbox environment(Sandbox mode provides an environment for modules to run without affecting other modules and Their private sandbox).

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

We want to emphasize here that becauseglobal variables inNode.jsare shared under multiple modules, try not to define properties in global.The definitions in the Demo are for ease of understanding.

Suppose we have a file1.jsin the same directory, which definesglobal.a = 100;. Now we introduce this file

requrie(./1); console.log(a); // 100
Copy after login

We can find that we do not define variable a in the current file, we just associate the two module files together. This is what I mentioned above, global variables inNode are shared under multiple modules.

The reason is that in theNodeenvironment, there is an execution context globally.

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

So,vm.runInThisContextcan access global variables onglobal, but cannot access custom variables. However,vm.runInNewContextcannot accessglobal, nor can it access custom variables. It exists in a brand new execution context.

And ourrequireis achieved throughvm.runInThisContext.

Implementationrequirecan be divided into the following four steps.

  • Read the files that need to be imported.

  • After reading the file, encapsulate the code into a function.

  • Convert it into JS syntax throughvm.runInThisContext.

  • Code call.

Suppose we now have the following two files. They area.jsandb.js

// 文件a通过module.exports导出一个变量,在文件b中使用require进行接收。 // a.js module.exports = "a" // b.js let a = require('./a'); console.log(a); // a
Copy after login

We can analyze the implementation logic of import and export through the above four steps.

  • Read the file.

    Introduce the content of the file that needs to be imported into the file that needs to be received, and it will look like this

    let a = module.exports = "a";
    Copy after login

    But in this form, Node cannot parse it at all, so we need Go to step two.

  • Encapsulate the read file into a function.

    let a = (function(exports, module, require, __dirname, __filename){ module.exports = "a"; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
    Copy after login

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

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

    // a.js var a = 100; module.exports = function(){}
    Copy after login

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

    let a = (function(exports, module, require, __dirname, __filename){ var a = 100; module.exports = function(){}; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
    Copy after login

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

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

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

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

  • 进行代码调用

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

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

    The above is the detailed content of A deep dive into the VM module in Node.js. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!