Модуль node:vm
(Virtual Machine) предоставляет API для компиляции и выполнения JavaScript-кода в изолированных контекстах. Вот что можно сделать с его помощью:
Базовый пример выполнения кода:
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
Можно контролировать доступ к глобальным объектам:
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);
Безопасное выполнение ненадежного кода:
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);
}
Реализация кастомной системы модулей:
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');
Статический анализ кода:
function analyzeCode(code) {
try {
new vm.Script(code);
return { valid: true };
} catch (err) {
return { valid: false, error: err.message };
}
}
Более мощная альтернатива шаблонным литералам:
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!
Запуск разных версий библиотек:
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
});
Динамическое применение полифиллов:
function applyPolyfills(code) {
const polyfills = `
if (!Array.prototype.flat) {
Array.prototype.flat = function() { /* имплементация */ }
}
`;
const fullCode = polyfills + code;
return new vm.Script(fullCode);
}
createContext
для ненадежного кодаtimeout
runInThisContext
для ненадежного кодаМодуль node:vm
- это мощный инструмент для сценариев, где требуется изоляция, безопасность или динамическое выполнение кода, но он требует осторожного использования из-за потенциальных рисков безопасности.