راهنمای جامع ماژول VM در Node.js (ماژول node:vm)

ماژول node:vm امکان کامپایل و اجرای کد جاوااسکریپت در کانتکست‌های ایزولهٔ V8 را فراهم می‌کند. این کانتکست‌ها مانند یک «سندباکس سبک» داخل برنامهٔ Node.js عمل می‌کنند و هرکدام globalThis مخصوص خود را دارند. این ماژول برای اجرای پویا، موتورهای قالب (Template Engines)، سیستم‌های افزونه (Plugin Systems)، REPLها و تست ایزولهٔ منطق بسیار مناسب است. اما نکتهٔ بسیار مهم: vm یک ابزار امنیتی نیست و نباید برای اجرای کدهای غیرقابل‌اعتماد استفاده شود.

VM Contextvm.runInContextvm.runInNewContextvm.runInThisContextvm.Script

~3 min read • Updated Dec 30, 2025

1. معرفی


ماژول node:vm APIهایی برای کامپایل و اجرای کد جاوااسکریپت در کانتکست‌های جداگانه ارائه می‌دهد. هر کانتکست globalThis مخصوص خود را دارد و کد داخل آن از محیط اصلی جداست. این قابلیت برای اجرای پویا، افزونه‌ها، موتورهای قالب و REPL بسیار کاربردی است.


2. دسترسی به ماژول


const vm = require('node:vm');

3. مفاهیم اصلی: کانتکست و ایزولیشن


Node.js کد را داخل یک V8 Context اجرا می‌کند. ماژول vm اجازه می‌دهد کانتکست‌های جدید بسازید تا کد در محیطی جدا از برنامهٔ اصلی اجرا شود.


4. ساخت یک کانتکست


const context = { foo: 'hello', console };
vm.createContext(context);

حالا context نقش globalThis را برای کد داخل کانتکست دارد.


5. روش‌های اجرای کد


5.1 vm.runInContext()


اجرای کد داخل یک کانتکست موجود.

vm.runInContext('foo += " world!"; console.log(foo)', context);
console.log(context.foo); // "hello world!"

5.2 vm.runInNewContext()


ساخت کانتکست جدید و اجرای کد داخل آن.

const result = vm.runInNewContext('a + b', { a: 10, b: 20 });
console.log(result); // 30

5.3 vm.runInThisContext()


اجرای کد در کانتکست فعلی Node.js — با دسترسی کامل به سیستم. بسیار خطرناک.

vm.runInThisContext('process.exit(1)');

5.4 vm.Script — کامپایل یک‌بار، اجرا چندبار


برای اجرای تکراری کد با سرعت بالا.

const script = new vm.Script('count += 1; name = "kitty"');

const context = { count: 0 };
vm.createContext(context);

for (let i = 0; i < 1000; i++) {
  script.runInContext(context);
}

console.log(context.count); // 1000

6. گزینه‌های مهم


{
  filename: 'my-script.vm',
  timeout: 1000,
  breakOnSigint: true,
  microtaskMode: 'afterEvaluate'
}

7. پشتیبانی از ماژول‌ها (Experimental)


نیازمند --experimental-vm-modules.

const module = new vm.SourceTextModule('export default 42');
await module.link(() => {});
await module.evaluate();
console.log(module.namespace.default); // 42

8. پشتیبانی از import() پویا


با استفاده از importModuleDynamically یا USE_MAIN_CONTEXT_DEFAULT_LOADER.


9. هشدار امنیتی بسیار مهم


vm یک سندباکس امنیتی نیست. هرگز کد غیرقابل‌اعتماد را با آن اجرا نکنید.

  • می‌تواند به internals دسترسی پیدا کند.
  • می‌تواند حلقهٔ رویداد را قفل کند.
  • می‌تواند از طریق prototype escape خارج شود.
  • ایزولیشن واقعی ندارد.

هرگز این کار را نکنید:

vm.runInNewContext(userCode, { require, process });

راهکارهای امن‌تر

  • استفاده از DONT_CONTEXTIFY
  • محدود کردن شدید sandbox
  • استفاده از timeout
  • برای امنیت واقعی: child_process، Worker Threads یا container

10. مثال‌های کاربردی


10.1 سندباکس ساده


const sandbox = {
  result: null,
  console: { log: (msg) => console.log('User:', msg) }
};
vm.createContext(sandbox);

vm.runInContext('result = 2 + 3 * 4', sandbox);
console.log(sandbox.result); // 14

10.2 موتور قالب ساده


function render(template, data) {
  const code = `with(data) { return \`${template}\`; }`;
  const fn = new vm.Script(code).runInNewContext({ data });
  return fn;
}

console.log(render('Hello {{name}}!', { name: 'Ali' }));

10.3 اندازه‌گیری حافظه


vm.measureMemory({ mode: 'detailed', execution: 'eager' })
  .then(info => console.log(info));

11. بهترین شیوه‌ها


  • همیشه از createContext() + runInContext() استفاده کنید.
  • هرگز require، process یا global را expose نکنید.
  • برای کدهای ناشناخته timeout بگذارید.
  • برای اجرای تکراری از vm.Script استفاده کنید.
  • برای async از microtaskMode: 'afterEvaluate' استفاده کنید.

نتیجه‌گیری


ماژول node:vm ابزاری قدرتمند برای اجرای پویا، سیستم‌های افزونه، موتورهای قالب و تست ایزولهٔ منطق است. اما نباید برای امنیت استفاده شود. با طراحی درست سندباکس و محدودسازی مناسب، vm می‌تواند اجرای کنترل‌شده و منعطف کد را در برنامه‌های Node.js فراهم کند.


Written & researched by Dr. Shahin Siami