Spec-Zone.ru › Deno 2

vm

Модуль node:vm позволяет компилировать и запускать код в контекстах виртуальной машины V8.

Модуль node:vm не является средством обеспечения безопасности. Не используйте его для запуска недоверенного кода.

Код JavaScript можно скомпилировать и запустить немедленно либо скомпилировать, сохранить и запустить позже.

Один из распространённых сценариев использования — запуск кода в другом контексте V8. Это означает, что у вызываемого кода другой глобальный объект, чем у вызывающего кода.

Контекст можно задать, contextifying объект. Вызываемый код рассматривает любое свойство контекста как глобальную переменную. Все изменения глобальных переменных, вызванные вызываемым кодом, отражаются в объекте контекста.

import vm from 'node:vm';

const x = 1;

const context = { x: 2 };
vm.createContext(context); // Contextify the object.

const code = 'x += 40; var y = 17;';
// `x` and `y` are global variables in the context.
// Initially, x has the value 2 because that is the value of context.x.
vm.runInContext(code, context);

console.log(context.x); // 42
console.log(context.y); // 17

console.log(x); // 1; y is not defined.

Использование в Deno

import * as mod from "node:vm";

класс Module

нестабильный

Использование в Deno

import { Module } from "node:vm";

Эта функция доступна только при включённом флаге команды --experimental-vm-modules.

Класс vm.Module предоставляет низкоуровневый интерфейс для использования модулей ECMAScript в контекстах VM. Он является аналогом класса vm.Script, который в точности соответствует записям модулей, определённым в спецификации ECMAScript.

Однако, в отличие от vm.Script, каждый объект vm.Module привязывается к контексту при создании. Операции с объектами vm.Module по своей природе асинхронны, в отличие от синхронных объектов vm.Script. Для работы с объектами vm.Module могут быть полезны функции «async».

Для использования объекта vm.Module требуется выполнить три отдельных шага: создание/разбор, связывание и вычисление. Эти три шага проиллюстрированы в следующем примере.

Эта реализация находится на более низком уровне, чем ECMAScript Module loader. Взаимодействовать с загрузчиком пока также невозможно, но такая поддержка запланирована.

import vm from 'node:vm';

const contextifiedObject = vm.createContext({
  secret: 42,
  print: console.log,
});

// Step 1
//
// Create a Module by constructing a new `vm.SourceTextModule` object. This
// parses the provided source text, throwing a `SyntaxError` if anything goes
// wrong. By default, a Module is created in the top context. But here, we
// specify `contextifiedObject` as the context this Module belongs to.
//
// Here, we attempt to obtain the default export from the module "foo", and
// put it into local binding "secret".

const bar = new vm.SourceTextModule(`
  import s from 'foo';
  s;
  print(s);
`, { context: contextifiedObject });

// Step 2
//
// "Link" the imported dependencies of this Module to it.
//
// The provided linking callback (the "linker") accepts two arguments: the
// parent module (`bar` in this case) and the string that is the specifier of
// the imported module. The callback is expected to return a Module that
// corresponds to the provided specifier, with certain requirements documented
// in `module.link()`.
//
// If linking has not started for the returned Module, the same linker
// callback will be called on the returned Module.
//
// Even top-level Modules without dependencies must be explicitly linked. The
// callback provided would never be called, however.
//
// The link() method returns a Promise that will be resolved when all the
// Promises returned by the linker resolve.
//
// Note: This is a contrived example in that the linker function creates a new
// "foo" module every time it is called. In a full-fledged module system, a
// cache would probably be used to avoid duplicated modules.

async function linker(specifier, referencingModule) {
  if (specifier === 'foo') {
    return new vm.SourceTextModule(`
      // The "secret" variable refers to the global variable we added to
      // "contextifiedObject" when creating the context.
      export default secret;
    `, { context: referencingModule.context });

    // Using `contextifiedObject` instead of `referencingModule.context`
    // here would work as well.
  }
  throw new Error(`Unable to resolve dependency: ${specifier}`);
}
await bar.link(linker);

// Step 3
//
// Evaluate the Module. The evaluate() method returns a promise which will
// resolve after the module has finished evaluating.

// Prints 42.
await bar.evaluate();

Свойства

context: Context
dependencySpecifiers: readonly string[]

Спецификаторы всех зависимостей этого модуля. Возвращаемый массив заморожен, чтобы предотвратить любые изменения.

Соответствует полю [[RequestedModules]] записи циклического модуля в спецификации ECMAScript.

error: any

Если module.status имеет значение 'errored', это свойство содержит исключение, вызванное модулем во время вычисления. При любом другом статусе обращение к этому свойству приведёт к вызову исключения.

Значение undefined нельзя использовать в случаях, когда исключение не было вызвано, поскольку его можно спутать со значением throw undefined;.

Соответствует полю [[EvaluationError]] записи циклического модуля в спецификации ECMAScript.

identifier: string

Идентификатор текущего модуля, заданный в конструкторе.

namespace: Object

Объект пространства имён модуля. Доступен только после завершения связывания (module.link()).

Соответствует абстрактной операции GetModuleNamespace в спецификации ECMAScript.

status: ModuleStatus

Текущий статус модуля. Может принимать одно из следующих значений:

  • 'unlinked': вызов module.link() ещё не выполнялся.
  • 'linking': вызов module.link() выполнен, но ещё не все промисы, возвращённые функцией связывания, разрешены.
  • 'linked': модуль успешно связан, и все его зависимости связаны, но вызов module.evaluate() ещё не выполнялся.
  • 'evaluating': выполняется вычисление модуля посредством module.evaluate() для него самого или родительского модуля.
  • 'evaluated': модуль успешно вычислен.
  • 'errored': модуль вычислен, но при этом было вызвано исключение.

За исключением 'errored', эта строка статуса соответствует полю [[Status]] записи Cyclic Module Record в спецификации. 'errored' соответствует значению 'evaluated' в спецификации, но при этом [[EvaluationError]] задано значением, отличным от undefined.

Методы

evaluate(options?: ModuleEvaluateOptions): Promise<void>

Вычисляет модуль.

Этот метод необходимо вызвать после связывания модуля; в противном случае промис будет отклонён. Его также можно вызвать, если модуль уже был вычислен. В этом случае метод либо ничего не сделает, если первоначальное вычисление завершилось успешно (module.status имеет значение 'evaluated'), либо повторно вызовет исключение, возникшее в результате первоначального вычисления (module.status имеет значение 'errored').

Этот метод нельзя вызывать во время вычисления модуля (module.status имеет значение 'evaluating').

Соответствует полю конкретного метода Evaluate() записи Cyclic Module Record в спецификации ECMAScript.

link(linker: ModuleLinker): Promise<void>

Связывает зависимости модуля. Этот метод необходимо вызвать до вычисления; для каждого модуля его можно вызвать только один раз.

Предполагается, что функция возвращает объект Module или объект Promise, который в конечном итоге разрешается в объект Module. Возвращаемый объект Module должен удовлетворять следующим двум инвариантам:

  • Он должен принадлежать тому же контексту, что и родительский Module.
  • Его status не должно иметь значение 'errored'.

Если status у возвращённого объекта Module имеет значение 'unlinked', этот метод будет рекурсивно вызван для возвращённого объекта Module с той же предоставленной функцией linker.

link() возвращает объект Promise, который будет разрешён, когда все экземпляры связывания разрешатся в допустимый Module, или отклонён, если функция связывания вызовет исключение либо вернёт недопустимый Module.

Функция связывания приблизительно соответствует определяемой реализацией абстрактной операции HostResolveImportedModule в спецификации ECMAScript, но имеет несколько важных отличий:

  • Функция связывания может быть асинхронной, тогда как HostResolveImportedModule является синхронной.

Фактическая реализация HostResolveImportedModule, используемая при связывании модулей, возвращает модули, связанные в ходе связывания. Поскольку к этому моменту все модули уже полностью связаны, реализация HostResolveImportedModule полностью синхронна в соответствии со спецификацией.

Соответствует полю конкретного метода Link() записи Cyclic Module Record в спецификации ECMAScript.


класс Script

Использование в Deno

import { Script } from "node:vm";
Совместимость с Deno

Параметр importModuleDynamically не поддерживается. Метод runInContext не поддерживает остановку на SIGINT.

Экземпляры класса vm.Script содержат предварительно скомпилированные сценарии, которые можно выполнять в определённых контекстах.

Конструкторы

Script(
code: string,
options?: ScriptOptions | string,
)
новый

Свойства

cachedData: Buffer | undefined
необязательный
cachedDataProduced: boolean | undefined
устаревший
необязательный
cachedDataRejected: boolean | undefined
необязательный

Если при создании vm.Script передан cachedData, это значение будет установлено в true или false в зависимости от того, приняты ли данные V8. В противном случае значение равно undefined.

sourceMapURL: string | undefined
необязательный

Если сценарий скомпилирован из исходного текста, содержащего специальный комментарий с source map, этому свойству будет присвоен URL карты исходного кода.

import vm from 'node:vm';

const script = new vm.Script(`
function myFunc() {}
//# sourceMappingURL=sourcemap.json
`);

console.log(script.sourceMapURL);
// Prints: sourcemap.json

Методы

createCachedData(): Buffer

Создаёт кэш кода, который можно использовать с параметром cachedData конструктора Script. Возвращает объект Buffer. Этот метод можно вызывать в любое время и любое количество раз.

Кэш кода Script не содержит состояний, наблюдаемых из JavaScript. Кэш кода безопасно хранить вместе с исходным текстом сценария и использовать для многократного создания новых экземпляров Script.

Функции в исходном тексте Script можно пометить для отложенной компиляции; в таком случае они не компилируются при создании Script. Эти функции будут скомпилированы при первом вызове. Кэш кода сериализует метаданные, известные V8 на данный момент о Script, которые можно использовать для ускорения будущих компиляций.

const script = new vm.Script(`
function add(a, b) {
  return a + b;
}

const x = add(1, 2);
`);

const cacheWithoutAdd = script.createCachedData();
// In `cacheWithoutAdd` the function `add()` is marked for full compilation
// upon invocation.

script.runInThisContext();

const cacheWithAdd = script.createCachedData();
// `cacheWithAdd` contains fully compiled function `add()`.
runInContext(
contextifiedObject: Context,
options?: RunningScriptOptions,
): any

Запускает скомпилированный код, содержащийся в объекте vm.Script, в заданном contextifiedObject и возвращает результат. Выполняемый код не имеет доступа к локальной области видимости.

В следующем примере компилируется код, который увеличивает глобальную переменную и задаёт значение другой глобальной переменной, после чего код выполняется несколько раз. Глобальные переменные находятся в объекте context.

import vm from 'node:vm';

const context = {
  animal: 'cat',
  count: 2,
};

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

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

console.log(context);
// Prints: { animal: 'cat', count: 12, name: 'kitty' }

Использование параметров timeout или breakOnSigint приведёт к созданию новых циклов событий и соответствующих потоков, что повлечёт ненулевые дополнительные затраты производительности.

runInNewContext(
contextObject?: Context | constants.DONT_CONTEXTIFY,
options?: RunningScriptInNewContextOptions,
): any

Этот метод является сокращённой формой вызова script.runInContext(vm.createContext(options), options). Он выполняет сразу несколько действий:

  1. Создаёт новый контекст.
  2. Если contextObject — объект, он контекстуализируется в новом контексте. Если contextObject не определён, создаётся новый объект и контекстуализируется. Если contextObject имеет значение vm.constants.DONT_CONTEXTIFY, контекстуализация не выполняется.
  3. Запускает скомпилированный код, содержащийся в объекте vm.Script, в созданном контексте. Код не имеет доступа к области видимости, в которой вызван этот метод.
  4. Возвращает результат.

В следующем примере компилируется код, который задаёт глобальную переменную, после чего выполняет этот код несколько раз в разных контекстах. Глобальные переменные задаются в каждом отдельном объекте context и хранятся в нём.

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

const script = new vm.Script('globalVar = "set"');

const contexts = [{}, {}, {}];
contexts.forEach((context) => {
  script.runInNewContext(context);
});

console.log(contexts);
// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]

// This would throw if the context is created from a contextified object.
// vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary
// global objects that can be frozen.
const freezeScript = new vm.Script('Object.freeze(globalThis); globalThis;');
const frozenContext = freezeScript.runInNewContext(vm.constants.DONT_CONTEXTIFY);
runInThisContext(options?: RunningScriptOptions): any

Запускает скомпилированный код, содержащийся в vm.Script, в контексте текущего объекта global. Выполняемый код не имеет доступа к локальной области видимости, но имеет доступ к текущему объекту global.

В следующем примере компилируется код, увеличивающий переменную global, после чего этот код выполняется несколько раз:

import vm from 'node:vm';

global.globalVar = 0;

const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });

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

console.log(globalVar);

// 1000

класс SourceTextModule

наследует Module
нестабильный

Использование в Deno

import { SourceTextModule } from "node:vm";

Эта функция доступна только при включённом флаге команды --experimental-vm-modules.

Класс vm.SourceTextModule предоставляет запись модуля с исходным текстом, определённую в спецификации ECMAScript.

Конструкторы

SourceTextModule(
code: string,
options?: SourceTextModuleOptions,
)
новый

Создаёт новый экземпляр SourceTextModule.


класс SyntheticModule

наследует Module
нестабильный

Использование в Deno

import { SyntheticModule } from "node:vm";

Эта функция доступна только при включённом флаге команды --experimental-vm-modules.

Класс vm.SyntheticModule предоставляет запись синтетического модуля, определённую в спецификации WebIDL. Синтетические модули предназначены для предоставления универсального интерфейса, позволяющего включать источники, не являющиеся JavaScript, в графы модулей ECMAScript.

import vm from 'node:vm';

const source = '{ "a": 1 }';
const module = new vm.SyntheticModule(['default'], function() {
  const obj = JSON.parse(source);
  this.setExport('default', obj);
});

// Use `module` in linking...

Конструкторы

SyntheticModule(
exportNames: string[],
evaluateCallback: (this: SyntheticModule) => void,
options?: SyntheticModuleOptions,
)
новый

Создаёт новый экземпляр SyntheticModule.

Методы

setExport(
name: string,
value: any,
): void

Этот метод используется после связывания модуля для задания значений экспортируемых элементов. Если вызвать его до связывания модуля, будет вызвана ошибка ERR_VM_MODULE_STATUS.

import vm from 'node:vm';

const m = new vm.SyntheticModule(['x'], () => {
  m.setExport('x', 1);
});

await m.link(() => {});
await m.evaluate();

assert.strictEqual(m.namespace.x, 1);

функция compileFunction

Использование в Deno

import { compileFunction } from "node:vm";
compileFunction(
code: string,
params?: readonly string[],
options?: CompileFunctionOptions,
): Function & { cachedData?: Script["cachedData"] | undefined; cachedDataProduced?: Script["cachedDataProduced"] | undefined; cachedDataRejected?: Script["cachedDataRejected"] | undefined; }

Компилирует указанный код в заданный контекст (если контекст не задан, используется текущий) и возвращает его в виде функции с указанным params.

Параметры

code: string

Тело компилируемой функции.

params: readonly string[]
необязательный

Массив строк, содержащий все параметры функции.

options: CompileFunctionOptions
необязательный

Тип возвращаемого значения

Function & { cachedData?: Script["cachedData"] | undefined; cachedDataProduced?: Script["cachedDataProduced"] | undefined; cachedDataRejected?: Script["cachedDataRejected"] | undefined; }

функция createContext

Использование в Deno

import { createContext } from "node:vm";
createContext(
contextObject?: Context | constants.DONT_CONTEXTIFY,
options?: CreateContextOptions,
): Context
Совместимость с Deno

Параметр importModuleDynamically не поддерживается.

Если указанный contextObject является объектом, метод vm.createContext() подготовит этот объект и вернёт ссылку на него, чтобы его можно было использовать при вызовах runInContext или script.runInContext(). В таких сценариях глобальный объект будет обёрнут в contextObject, сохранив все существующие свойства и получив встроенные объекты и функции, имеющиеся у любого стандартного глобального объекта. За пределами сценариев, выполняемых модулем vm, глобальные переменные останутся неизменными.

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

global.globalVar = 3;

const context = { globalVar: 1 };
vm.createContext(context);

vm.runInContext('globalVar *= 2;', context);

console.log(context);
// Prints: { globalVar: 2 }

console.log(global.globalVar);
// Prints: 3

Если contextObject не указан (или явно передан как undefined), будет возвращён новый пустой контекстуализированный объект.

Контекстуализированный глобальный объект в новом контексте имеет некоторые особенности по сравнению с обычными глобальными объектами. Например, его нельзя заморозить. Чтобы создать контекст без особенностей контекстуализации, передайте vm.constants.DONT_CONTEXTIFY в качестве аргумента contextObject. Подробности см. в документации vm.constants.DONT_CONTEXTIFY.

Метод vm.createContext() главным образом предназначен для создания единственного контекста, который можно использовать для запуска нескольких сценариев. Например, при эмуляции веб-браузера этот метод можно использовать для создания единственного контекста, представляющего глобальный объект окна, а затем запускать в этом контексте все теги <script>.

Предоставленные name и origin контекста доступны через API Inspector.

Параметры

contextObject: Context | constants.DONT_CONTEXTIFY
необязательный

Либо vm.constants.DONT_CONTEXTIFY, либо объект, который будет контекстуализирован. Для обратной совместимости, если указано undefined, будет создан пустой контекстуализированный объект.

options: CreateContextOptions
необязательный

Тип возвращаемого значения

Context

Контекстуализированный объект.


функция isContext

Использование в Deno

import { isContext } from "node:vm";
isContext(sandbox: Context): boolean

Возвращает true, если указанный объект object был контекстуализирован с помощью createContext или является глобальным объектом контекста, созданного с помощью vm.constants.DONT_CONTEXTIFY.

Параметры

sandbox: Context

Тип возвращаемого значения

boolean

функция measureMemory

нестабильный

Использование в Deno

import { measureMemory } from "node:vm";
measureMemory(options?: MeasureMemoryOptions): Promise<MemoryMeasurement>
Совместимость с Deno

Это неработающая заглушка.

Измеряет объем памяти, известный V8 и используемый всеми контекстами, известными текущему изоляту V8, либо основным контекстом.

Формат объекта, который может быть передан возвращаемым Promise, зависит от движка V8 и может изменяться от одной версии V8 к другой.

Возвращаемый результат отличается от статистики, возвращаемой v8.getHeapSpaceStatistics(): vm.measureMemory() измеряют память, доступную из каждого специфичного для V8 контекста в текущем экземпляре движка V8, тогда как результат v8.getHeapSpaceStatistics() измеряет память, занимаемую каждым пространством кучи в текущем экземпляре V8.

import vm from 'node:vm';
// Measure the memory used by the main context.
vm.measureMemory({ mode: 'summary' })
  // This is the same as vm.measureMemory()
  .then((result) => {
    // The current format is:
    // {
    //   total: {
    //      jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ]
    //    }
    // }
    console.log(result);
  });

const context = vm.createContext({ a: 1 });
vm.measureMemory({ mode: 'detailed', execution: 'eager' })
  .then((result) => {
    // Reference the context here so that it won't be GC'ed
    // until the measurement is complete.
    console.log(context.a);
    // {
    //   total: {
    //     jsMemoryEstimate: 2574732,
    //     jsMemoryRange: [ 2574732, 2904372 ]
    //   },
    //   current: {
    //     jsMemoryEstimate: 2438996,
    //     jsMemoryRange: [ 2438996, 2768636 ]
    //   },
    //   other: [
    //     {
    //       jsMemoryEstimate: 135736,
    //       jsMemoryRange: [ 135736, 465376 ]
    //     }
    //   ]
    // }
    console.log(result);
  });

Параметры

options: MeasureMemoryOptions
необязательный

Тип возвращаемого значения

Promise<MemoryMeasurement>

функция runInContext

Использование в Deno

import { runInContext } from "node:vm";
runInContext(
code: string,
contextifiedObject: Context,
options?: RunningCodeOptions | string,
): any

Метод vm.runInContext() компилирует code, выполняет его в контексте contextifiedObject, а затем возвращает результат. Выполняемый код не имеет доступа к локальной области видимости. Объект contextifiedObject должен быть предварительно contextified с помощью метода createContext.

Если options — строка, она указывает имя файла.

В следующем примере компилируются и выполняются разные скрипты с использованием одного объекта contextified:

import vm from 'node:vm';

const contextObject = { globalVar: 1 };
vm.createContext(contextObject);

for (let i = 0; i < 10; ++i) {
  vm.runInContext('globalVar *= 2;', contextObject);
}
console.log(contextObject);
// Prints: { globalVar: 1024 }

Параметры

code: string

Код JavaScript для компиляции и выполнения.

contextifiedObject: Context

Объект contextified, который будет использоваться как global при компиляции и выполнении code.

options: RunningCodeOptions | string
необязательный

Тип возвращаемого значения

any

результат выполнения последнего оператора скрипта.


функция runInNewContext

Использование в Deno

import { runInNewContext } from "node:vm";
runInNewContext(
code: string,
contextObject?: Context | constants.DONT_CONTEXTIFY,
options?: RunningCodeInNewContextOptions | string,
): any

Этот метод является сокращенной формой (new vm.Script(code, options)).runInContext(vm.createContext(options), options). Если options — строка, она указывает имя файла.

Он выполняет несколько действий одновременно:

  1. Создает новый контекст.
  2. Если contextObject является объектом, контекстуализирует его в новом контексте. Если contextObject не определено, создает новый объект и контекстуализирует его. Если contextObject — vm.constants.DONT_CONTEXTIFY, ничего не контекстуализирует.
  3. Компилирует код как vm.Script
  4. Выполняет скомпилированный код в созданном контексте. Код не имеет доступа к области видимости, в которой вызван этот метод.
  5. Возвращает результат.

В следующем примере компилируется и выполняется код, который увеличивает глобальную переменную и задает новую. Эти глобальные переменные содержатся в contextObject.

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

const contextObject = {
  animal: 'cat',
  count: 2,
};

vm.runInNewContext('count += 1; name = "kitty"', contextObject);
console.log(contextObject);
// Prints: { animal: 'cat', count: 3, name: 'kitty' }

// This would throw if the context is created from a contextified object.
// vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary global objects that
// can be frozen.
const frozenContext = vm.runInNewContext('Object.freeze(globalThis); globalThis;', vm.constants.DONT_CONTEXTIFY);

Параметры

code: string

Код JavaScript для компиляции и выполнения.

contextObject: Context | constants.DONT_CONTEXTIFY
необязательный

Либо vm.constants.DONT_CONTEXTIFY, либо объект, который будет контекстуализирован. Если undefined, для обеспечения обратной совместимости будет создан пустой контекстуализированный объект.

options: RunningCodeInNewContextOptions | string
необязательный

Тип возвращаемого значения

any

результат выполнения последнего оператора скрипта.


функция runInThisContext

Использование в Deno

import { runInThisContext } from "node:vm";
runInThisContext(
code: string,
options?: RunningCodeOptions | string,
): any

vm.runInThisContext() компилирует code, выполняет его в контексте текущего global и возвращает результат. Выполняемый код не имеет доступа к локальной области видимости, но имеет доступ к текущему объекту global.

Если options — строка, она указывает имя файла.

В следующем примере показано использование vm.runInThisContext() и функции JavaScript eval() для выполнения одного и того же кода:

import vm from 'node:vm';
let localVar = 'initial value';

const vmResult = vm.runInThisContext('localVar = "vm";');
console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
// Prints: vmResult: 'vm', localVar: 'initial value'

const evalResult = eval('localVar = "eval";');
console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`);
// Prints: evalResult: 'eval', localVar: 'eval'

Поскольку vm.runInThisContext() не имеет доступа к локальной области видимости, localVar не изменяется. В отличие от него, eval() имеет доступ к локальной области видимости, поэтому значение localVar изменяется. В этом смысле vm.runInThisContext() во многом напоминает непрямой вызов eval(), например (0,eval)('code').

Пример: запуск HTTP-сервера в виртуальной машине

При использовании script.runInThisContext() или runInThisContext код выполняется в текущем глобальном контексте V8. Код, переданный в этот контекст VM, будет иметь собственную изолированную область видимости.

Чтобы запустить простой веб-сервер с помощью модуля node:http, код, передаваемый в контекст, должен либо самостоятельно импортировать node:http, либо получить ссылку на модуль node:http. Например:

'use strict';
import vm from 'node:vm';

const code = `
((require) => {
const http = require('node:http');

  http.createServer((request, response) => {
    response.writeHead(200, { 'Content-Type': 'text/plain' });
    response.end('Hello World\\n');
  }).listen(8124);

  console.log('Server running at http://127.0.0.1:8124/');
})`;

vm.runInThisContext(code)(require);

В данном случае require() совместно использует состояние с контекстом, из которого он был передан. Это может создавать риски при выполнении недоверенного кода, например, нежелательное изменение объектов в контексте.

Параметры

code: string

Код JavaScript для компиляции и выполнения.

options: RunningCodeOptions | string
необязательный

Тип возвращаемого значения

any

результат выполнения последнего оператора скрипта.


интерфейс BaseOptions

Использование в Deno

import { type BaseOptions } from "node:vm";

Свойства

filename: string | undefined
необязательный

Задает имя файла, используемое в трассировках стека, формируемых этим скриптом.

lineOffset: number | undefined
необязательный

Задает смещение номера строки, отображаемое в трассировках стека, формируемых этим скриптом.

columnOffset: number | undefined
необязательный

Задает смещение номера столбца, отображаемое в трассировках стека, формируемых этим скриптом.


интерфейс CompileFunctionOptions

расширяет BaseOptions

Использование в Deno

import { type CompileFunctionOptions } from "node:vm";

Свойства

cachedData: Buffer | undefined
необязательный

Предоставляет необязательные данные кэша кода V8 для указанного исходного кода.

produceCachedData: boolean | undefined
необязательный

Указывает, следует ли создавать новые данные кэша.

parsingContext: Context | undefined
необязательный

Песочница/контекст, в котором должна быть скомпилирована указанная функция.

contextExtensions: Object[] | undefined
необязательный

Массив, содержащий набор расширений контекста (объектов, оборачивающих текущую область видимости), которые применяются при компиляции


интерфейс Context

расширяет [NodeJS.Dict]<any>

Использование в Deno

import { type Context } from "node:vm";

интерфейс CreateContextOptions

Использование в Deno

import { type CreateContextOptions } from "node:vm";

Свойства

name: string | undefined
необязательный

Понятное человеку имя вновь созданного контекста.

origin: string | undefined
необязательный

Указывает источник вновь созданного контекста для отображения. Источник должен быть отформатирован как URL, но содержать только схему, хост и порт (если он необходим), как значение свойства url.origin объекта URL. В частности, эта строка не должна содержать завершающую косую черту, поскольку она обозначает путь.

codeGeneration: { strings?: boolean | undefined; wasm?: boolean | undefined; } | undefined
необязательный
microtaskMode: "afterEvaluate" | undefined
необязательный

Если задано значение afterEvaluate, микрозадачи будут выполнены сразу после завершения скрипта.


интерфейс MeasureMemoryOptions

Использование в Deno

import { type MeasureMemoryOptions } from "node:vm";

Свойства

mode: MeasureMemoryMode | undefined
необязательный
execution:
"default"
| "eager"
| undefined
необязательный

интерфейс MemoryMeasurement

Использование в Deno

import { type MemoryMeasurement } from "node:vm";

Свойства

total: { jsMemoryEstimate: number; jsMemoryRange: [number, number]; }

интерфейс ModuleEvaluateOptions

Использование в Deno

import { type ModuleEvaluateOptions } from "node:vm";

Свойства

timeout: RunningScriptOptions["timeout"] | undefined
необязательный
breakOnSigint: RunningScriptOptions["breakOnSigint"] | undefined
необязательный

интерфейс RunningCodeInNewContextOptions

расширяет RunningScriptInNewContextOptions

Использование в Deno

import { type RunningCodeInNewContextOptions } from "node:vm";

Свойства

cachedData: ScriptOptions["cachedData"]
необязательный
importModuleDynamically: ScriptOptions["importModuleDynamically"]
необязательный

интерфейс RunningCodeOptions

расширяет RunningScriptOptions

Использование в Deno

import { type RunningCodeOptions } from "node:vm";

Свойства

cachedData: ScriptOptions["cachedData"]
необязательный
importModuleDynamically: ScriptOptions["importModuleDynamically"]
необязательный

интерфейс RunningScriptInNewContextOptions

расширяет RunningScriptOptions

Использование в Deno

import { type RunningScriptInNewContextOptions } from "node:vm";

Свойства

contextName: CreateContextOptions["name"]
необязательный

Понятное человеку имя вновь созданного контекста.

contextOrigin: CreateContextOptions["origin"]
необязательный

Источник, соответствующий вновь созданному контексту и предназначенный для отображения. Источник должен быть отформатирован как URL, но содержать только схему, хост и порт (если необходимо), как значение свойства url.origin объекта URL. В частности, эта строка не должна содержать завершающую косую черту, поскольку она обозначает путь.

contextCodeGeneration: CreateContextOptions["codeGeneration"]
необязательный
microtaskMode: CreateContextOptions["microtaskMode"]
необязательный

Если задано значение afterEvaluate, микрозадачи будут выполнены сразу после выполнения скрипта.


интерфейс RunningScriptOptions

расширяет BaseOptions

Использование в Deno

import { type RunningScriptOptions } from "node:vm";

Свойства

displayErrors: boolean | undefined
необязательный

Если значение true, то при возникновении Error во время компиляции code строка кода, вызвавшая ошибку, добавляется в трассировку стека.

timeout: number | undefined
необязательный

Задает количество миллисекунд, в течение которых должен выполняться код до прекращения выполнения. Если выполнение прекращено, будет выброшено исключение Error. Это значение должно быть строго положительным целым числом.

breakOnSigint: boolean | undefined
необязательный

Если значение true, выполнение будет прекращено при получении SIGINT (Ctrl+C). Существующие обработчики этого события, добавленные через process.on('SIGINT'), будут отключены на время выполнения скрипта, но продолжат работать после его завершения. Если выполнение прекращено, будет выброшено исключение Error.


интерфейс ScriptOptions

расширяет BaseOptions

Использование в Deno

import { type ScriptOptions } from "node:vm";

Свойства

cachedData:
Buffer
| ArrayBufferView
| undefined
необязательный

Данные кэша кода V8 для предоставленного исходного кода.

produceCachedData: boolean | undefined
устаревший
необязательный
importModuleDynamically:
((
specifier: string,
script: Script,
importAttributes: ImportAttributes,
) => Module | Promise<Module>)

| constants.USE_MAIN_CONTEXT_DEFAULT_LOADER
| undefined
необязательный

Используется для указания способа загрузки модулей при вычислении этого скрипта, когда вызывается import(). Эта опция является частью экспериментального API модулей. Не рекомендуется использовать ее в рабочей среде. Подробную информацию см. в разделе Поддержка динамического import() в API компиляции.


интерфейс SourceTextModuleOptions

Использование в Deno

import { type SourceTextModuleOptions } from "node:vm";

Свойства

identifier: string | undefined
необязательный

Строка, используемая в трассировках стека.

cachedData: ScriptOptions["cachedData"] | undefined
необязательный
context: Context | undefined
необязательный
lineOffset: BaseOptions["lineOffset"] | undefined
необязательный
columnOffset: BaseOptions["columnOffset"] | undefined
необязательный
initializeImportMeta: ((
meta: ImportMeta,
module: SourceTextModule,
) => void) | undefined
необязательный

Вызывается при вычислении этого модуля для инициализации import.meta.

importModuleDynamically: ScriptOptions["importModuleDynamically"] | undefined
необязательный

интерфейс SyntheticModuleOptions

Использование в Deno

import { type SyntheticModuleOptions } from "node:vm";

Свойства

identifier: string | undefined
необязательный

Строка, используемая в трассировках стека.

context: Context | undefined
необязательный

Контекстизированный объект, возвращаемый методом vm.createContext(), в котором компилируется и вычисляется этот модуль.


пространство имен constants

Использование в Deno

import { constants } from "node:vm";

Возвращает объект, содержащий часто используемые константы для операций с виртуальной машиной.

Переменные

constants.DONT_CONTEXTIFY

Эта константа, используемая в качестве аргумента contextObject в API vm, указывает Node.js создать контекст, не оборачивая его глобальный объект в другой объект специфичным для Node.js способом. В результате значение globalThis внутри нового контекста будет вести себя более похоже на обычное.

constants.USE_MAIN_CONTEXT_DEFAULT_LOADER

Константа, которую можно использовать в качестве опции importModuleDynamically для vm.Script и vm.compileFunction(), чтобы Node.js использовал загрузчик ESM по умолчанию из основного контекста для загрузки запрошенного модуля.


псевдоним типа MeasureMemoryMode

Использование в Deno

import { type MeasureMemoryMode } from "node:vm";

Определение

"summary" | "detailed"

псевдоним типа ModuleLinker

Использование в Deno

import { type ModuleLinker } from "node:vm";

Определение

(
specifier: string,
referencingModule: Module,
extra: { attributes: ImportAttributes; },
) => Module | Promise<Module>

псевдоним типа ModuleStatus

Использование в Deno

import { type ModuleStatus } from "node:vm";

Определение

"unlinked"
| "linking"
| "linked"
| "evaluating"
| "evaluated"
| "errored"

переменная constants.DONT_CONTEXTIFY

Использование в Deno

import { constants } from "node:vm";

Эта константа, используемая в качестве аргумента contextObject в API vm, указывает Node.js создать контекст, не оборачивая его глобальный объект в другой объект специфичным для Node.js способом. В результате значение globalThis внутри нового контекста будет вести себя более похоже на обычное.

Если vm.constants.DONT_CONTEXTIFY используется в качестве аргумента contextObject для createContext, возвращаемый объект является объектом, похожим на прокси, для глобального объекта во вновь созданном контексте и имеет меньше особенностей, специфичных для Node.js. Он равен по ссылке значению globalThis в новом контексте, может быть изменен извне контекста и может использоваться для прямого доступа к встроенным объектам нового контекста.

Тип

number

переменная constants.USE_MAIN_CONTEXT_DEFAULT_LOADER

Использование в Deno

import { constants } from "node:vm";

Константа, которую можно использовать в качестве опции importModuleDynamically для vm.Script и vm.compileFunction(), чтобы Node.js использовал загрузчик ESM по умолчанию из основного контекста для загрузки запрошенного модуля.

Подробную информацию см. в разделе Поддержка динамического import() в API компиляции.

Тип

number

© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/api/node/vm

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API