Node.js의 VM 모듈에 대한 심층 분석
VM 모듈은 NodeJS의 핵심 모듈이며 NodeJS의 작동 메커니즘을 지원합니다. 때로는 VM 템플릿을 사용하여 몇 가지 특별한 작업을 수행할 수도 있습니다. 이 글이 Node의 VM 모듈에 대해 자세히 이해하는 데 도움이 되기를 바랍니다.
참조 vm 가상 머신 | Node 공식 홈페이지
http://nodejs.cn/api/vm.html
이전 기사에서 문제를 언급했습니다.
문자열을 JS로 변환하여 실행하려면 어떻게 해야 하나요?
2가지 방법, 즉 eval function과 new Function을 자세히 소개했습니다.
여기서 Function
생성자로 생성된 함수는 현재 환경의 클로저를 생성하지 않는다는 점을 다시 강조해야 합니다. 이 함수는 항상 전역 환경에서 생성되므로 런타임 전역에서만 액세스할 수 있습니다. 변수 및 자체 지역 변수는 함수
생성자에 의해 생성된 범위의 변수에 액세스할 수 없습니다. 이는 eval
Function
构造器创建的函数不会创建当前环境的闭包,它们总是被创建于全局环境,因此在运行时它们只能访问全局变量和自己的局部变量,不能访问它们被 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
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
在这里我们要强调一下,因为 在Node.js中全局变量是在多个模块下共享的,所以尽量不要在global中定义属性。 Demo中的定义是为了方便理解。
假设我们在同级目录下有一个文件 1.js ,里面定义了 global.a = 100;
。 现在我们引入这个文件
requrie(./1); console.log(a); // 100
我们可以发现,在当前文件中我们并没有定义变量a,仅仅只是把两个模块文件关联在了一起。这就是我上面提到的,Node中全局变量是在多个模块下共享的。
他的原理是因为在 Node 的环境中,全局中有一个执行上下文。
// 模拟一下Node的全局环境 // vm.runInThisContext在当前全局环境执行,但不会产生新函数 - function(exports, module, require, __dirname, __filename){ // ... } - vm.runInThisContext ... // vm.runInNewContext在全局环境之外执行 vm.runInNewContext ...
所以,vm.runInThisContext
可以访问到 global
上的全局变量,但是访问不到自定义的变量。而 vm.runInNewContext
访问不到 global
,也访问不到自定义变量,他存在于一个全新的执行上下文。
而我们require
就是通过 vm.runInThisContext
实现的。
实现require
主要可以分为以下四步。
读取需要引入的文件。
读取到文件后,将代码封装成一个函数。
通过
vm.runInThisContext
생성 기능을 실행하는 코드가 다릅니다.// 文件a通过module.exports导出一个变量,在文件b中使用require进行接收。 // a.js module.exports = "a" // b.js let a = require('./a'); console.log(a); // a
로그인 후 복사- 모듈 엔진
의 구현 원리입니다. 추후 별도로 설명하는 글을 게시하겠습니다.
지난 기사에서 자세히 설명하지 않은 또 다른 솔루션이 있는데, 바로
함수
는 전역 변수를 얻을 수 있으므로 여전히 변수 오염이 있을 수 있습니다. 함수
는 vm
모듈입니다. vm 모듈
위 텍스트에서 저는 변수의 오염. VM의 특징은 환경에 영향을 받지 않는다는 점입니다. 샌드박스 환경이라고도 할 수 있습니다. (샌드박스 모드는 다른 모듈에 영향을 주지 않고 모듈이 실행될 수 있는 환경을 제공하며, ).
let a = module.exports = "a";
여기서 강조하고 싶은 점은
Node.js- 의 전역 변수가 여러 모듈에서 공유되므로 전역에서 속성을 정의하지 않도록 하세요. 데모의 정의는 이해를 돕기 위한 것입니다.
같은 디렉토리에
global.a = 100;
을 정의하는 1.js 파일이 있다고 가정해 보겠습니다. 이제 이 파일을 소개하므로(let a = (function(exports, module, require, __dirname, __filename){ module.exports = "a"; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
로그인 후 복사로그인 후 복사) 현재 파일에서 변수 a를 정의하지 않고 두 모듈 파일을 함께 연결한다는 것을 알 수 있습니다. 위에서 언급한 내용은 노드의 전역 변수가 여러 모듈에서 공유된다는 것입니다.
그 이유는
Node 환경에는 전역적으로 실행 컨텍스트가 있기 때문입니다. // a.js var a = 100; module.exports = function(){}
로그인 후 복사로그인 후 복사그래서
🎜vm.runInThisContext
는global
의 전역 변수에 액세스할 수 있지만 사용자 정의 변수에는 액세스할 수 없습니다. 그러나vm.runInNewContext
는전역
에 액세스할 수 없으며 사용자 정의 변수에도 액세스할 수 없습니다. 그리고require
는vm.runInThisContext
를 통해 구현됩니다.require
구현은 다음 네 단계로 나눌 수 있습니다. 🎜🎜🎜🎜가져와야 하는 파일을 읽어보세요. 🎜🎜🎜🎜파일을 읽은 후 코드를 함수로 캡슐화하세요. 🎜🎜🎜🎜vm.runInThisContext
를 통해 JS 구문으로 변환하세요. 🎜🎜🎜🎜코드콜. 🎜🎜🎜🎜이제 다음 두 파일이 있다고 가정합니다. 🎜a.js🎜 및 🎜b.js🎜🎜🎜입니다. 위의 4단계를 통해 가져오기 및 내보내기의 구현 로직을 분석할 수 있습니다. 🎜🎜🎜🎜🎜파일을 읽어보세요. 🎜🎜🎜수신해야 할 파일에 import해야 할 파일의 내용을 소개하면 이런 모습이 됩니다🎜rrreee🎜그런데 이 형태에서는 Node가 전혀 파싱을 할 수 없기 때문에 계속 진행해야 합니다. 두 번째 단계. 🎜🎜🎜🎜🎜읽은 파일을 함수로 캡슐화합니다. 🎜🎜let a = (function(exports, module, require, __dirname, __filename){ var a = 100; module.exports = function(){}; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
로그인 후 복사로그인 후 복사let a = (function(exports, module, require, __dirname, __filename){ module.exports = "a"; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
로그인 후 복사로그인 후 복사封装成函数的原因,我们可以参考下面这个例子。
假设我们现在传入的不是字符串,而是一个函数。
// a.js var a = 100; module.exports = function(){}
로그인 후 복사로그인 후 복사这样我们在解析的时候,就会被解析成下面这种格式
let a = (function(exports, module, require, __dirname, __filename){ var a = 100; module.exports = function(){}; return module.exports })(...args) // exports, module, require, __dirname, __filename 将五个参数传入
로그인 후 복사로그인 후 복사我们导出的是
module.exports
,所以在模块文件中定义的变量a,也只属于当前这个执行上下文。在解析的时候,变量a 会被放到函数中。真正的实现了 作用域分离。
-
vm.runInThisContext
解析成可执行的Js代码我们处理过的代码会以字符串的形式存在,所以我们需要通过
vm.runInThisContext
将字符串进行解析。 -
进行代码调用
在此之前,我们其实还需要对代码进行调试。
更多node相关知识,请访问:nodejs 教程!!
위 내용은 Node.js의 VM 모듈에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

이 기사는 NodeJS V8 엔진의 메모리 및 가비지 수집기(GC)에 대한 심층적인 이해를 제공할 것입니다. 도움이 되기를 바랍니다.

Non-Blocking, Event-Driven 기반으로 구축된 Node 서비스는 메모리 소모가 적다는 장점이 있으며, 대규모 네트워크 요청을 처리하는데 매우 적합합니다. 대규모 요청을 전제로 '메모리 제어'와 관련된 문제를 고려해야 합니다. 1. V8의 가비지 수집 메커니즘과 메모리 제한 Js는 가비지 수집 기계에 의해 제어됩니다.

Node용 Docker 이미지를 선택하는 것은 사소한 문제처럼 보일 수 있지만 이미지의 크기와 잠재적인 취약점은 CI/CD 프로세스와 보안에 상당한 영향을 미칠 수 있습니다. 그렇다면 최고의 Node.js Docker 이미지를 어떻게 선택합니까?

Node 19가 정식 출시되었습니다. 이 글에서는 Node.js 19의 6가지 주요 기능에 대해 자세히 설명하겠습니다. 도움이 되셨으면 좋겠습니다!

파일 모듈은 파일 읽기/쓰기/열기/닫기/삭제 추가 등과 같은 기본 파일 작업을 캡슐화한 것입니다. 파일 모듈의 가장 큰 특징은 모든 메소드가 **동기** 및 ** 두 가지 버전을 제공한다는 것입니다. 비동기**, sync 접미사가 있는 메서드는 모두 동기화 메서드이고, 없는 메서드는 모두 이기종 메서드입니다.

이벤트 루프는 Node.js의 기본 부분이며 메인 스레드가 차단되지 않도록 하여 비동기 프로그래밍을 가능하게 합니다. 이벤트 루프를 이해하는 것은 효율적인 애플리케이션을 구축하는 데 중요합니다. 다음 기사는 Node.js의 이벤트 루프에 대한 심층적인 이해를 제공할 것입니다. 도움이 되기를 바랍니다!

nodejs 실행 파일을 pkg로 패키징하는 방법은 무엇입니까? 다음 기사에서는 pkg를 사용하여 Node 프로젝트를 실행 파일로 패키징하는 방법을 소개합니다. 도움이 되기를 바랍니다.

Node.js는 GC(가비지 수집)를 어떻게 수행하나요? 다음 기사에서는 이에 대해 설명합니다.
