Что можно сделать при помощи node:vm (любые примеры)?nodejs-18

Модуль node:vm (Virtual Machine) предоставляет API для компиляции и выполнения JavaScript-кода в изолированных контекстах. Вот что можно сделать с его помощью:

1. Выполнение кода в изолированном контексте

Базовый пример выполнения кода:

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

const script = new vm.Script('let x = 5; let y = 10; x + y');
const result = script.runInThisContext();

console.log(result); // 15

2. Создание песочниц с ограниченным доступом

Можно контролировать доступ к глобальным объектам:

const context = vm.createContext({
  console: {
    log: (...args) => {
      // Кастомная реализация console.log
      process.stdout.write('SANDBOX: ' + args.join(' ') + '\n');
    }
  },
  setTimeout // разрешаем только setTimeout
});

vm.runInContext(`
  console.log("Hello from sandbox");
  setTimeout(() => console.log("Delayed"), 1000);
  // process.exit() вызовет ошибку - process не доступен
`, context);

3. Динамическое выполнение пользовательского кода

Безопасное выполнение ненадежного кода:

function safeEval(code) {
  const context = vm.createContext({});
  return vm.runInContext(code, context, { timeout: 100 });
}

try {
  const result = safeEval('2 + 2');
  console.log(result); // 4
} catch (err) {
  console.error('Execution error:', err);
}

4. Модульные системы и загрузчики

Реализация кастомной системы модулей:

const customRequire = (moduleName) => {
  const code = fs.readFileSync(moduleName, 'utf8');
  const context = vm.createContext({ module: {}, exports: {} });
  vm.runInContext(code, context);
  return context.exports;
};

const myModule = customRequire('./my-module.js');

5. Тестирование и анализ кода

Статический анализ кода:

function analyzeCode(code) {
  try {
    new vm.Script(code);
    return { valid: true };
  } catch (err) {
    return { valid: false, error: err.message };
  }
}

6. Шаблонизация с продвинутыми возможностями

Более мощная альтернатива шаблонным литералам:

function render(template, data) {
  const context = vm.createContext({ ...data });
  return vm.runInContext('`' + template + '`', context);
}

const result = render('Hello ${name}!', { name: 'Alice' });
console.log(result); // Hello Alice!

7. Изоляция зависимостей

Запуск разных версий библиотек:

function loadLibrary(version, callback) {
  const libCode = getLibraryCode(version); // ваша логика загрузки
  const context = vm.createContext({ callback });
  vm.runInContext(libCode, context);
}

loadLibrary('1.0.0', (api) => {
  // работаем с API версии 1.0.0
});

8. Полифиллы и транспиляция

Динамическое применение полифиллов:

function applyPolyfills(code) {
  const polyfills = `
    if (!Array.prototype.flat) {
      Array.prototype.flat = function() { /* имплементация */ }
    }
  `;
  const fullCode = polyfills + code;
  return new vm.Script(fullCode);
}

Важные особенности безопасности

  1. Всегда используйте createContext для ненадежного кода
  2. Ограничивайте время выполнения через timeout
  3. Контролируйте доступ к глобальным объектам
  4. Не используйте runInThisContext для ненадежного кода

Резюмируем

  1. Изоляция кода - безопасное выполнение ненадежных скриптов
  2. Кастомные среды - создание специализированных контекстов выполнения
  3. Песочницы - ограничение доступа к API Node.js
  4. Динамическое выполнение - реализация eval с контролем безопасности
  5. Тестирование - анализ синтаксиса без выполнения
  6. Шаблонизация - продвинутые шаблоны с логикой
  7. Версионирование - изолированное выполнение разных версий библиотек

Модуль node:vm - это мощный инструмент для сценариев, где требуется изоляция, безопасность или динамическое выполнение кода, но он требует осторожного использования из-за потенциальных рисков безопасности.