- Node.js Version: 15.0
- OS: MacOS
- Scope (install, code, runtime, meta, other?): code
- Module (and version) (if relevant):
Hi, Im trying out the C++ embedder API and one thing I'm confused about is multiple runs of a script in the same environment. In the code below (taken from the NodeJS docs) a new environment setup is created per script run, and if I'm understanding it correctly it creates its own event loop, isolate, and context. And then when we load a node environment itll take all those and execute a script within that environment. I want to be able to reduce the amount of overhead in running a script, is it possible to share this CommonEnvironmentSetup object? Can we have say, a class that creates V8, initializes node and an event loop + isolate + anything else we need and then have a method in that class that just injects the script into the environment and runs it?
int RunNodeInstance(MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args) {
int exit_code = 0;
// Setup up a libuv event loop, v8::Isolate, and Node.js Environment.
std::vector<std::string> errors;
std::unique_ptr<CommonEnvironmentSetup> setup =
CommonEnvironmentSetup::Create(platform, &errors, args, exec_args);
if (!setup) {
for (const std::string& err : errors)
fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
return 1;
}
Isolate* isolate = setup->isolate();
Environment* env = setup->env();
{
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
// The v8::Context needs to be entered when node::CreateEnvironment() and
// node::LoadEnvironment() are being called.
Context::Scope context_scope(setup->context());
// Set up the Node.js instance for execution, and run code inside of it.
// There is also a variant that takes a callback and provides it with
// the `require` and `process` objects, so that it can manually compile
// and run scripts as needed.
// The `require` function inside this script does *not* access the file
// system, and can only load built-in Node.js modules.
// `module.createRequire()` is being used to create one that is able to
// load files from the disk, and uses the standard CommonJS file loader
// instead of the internal-only `require` function.
MaybeLocal<Value> loadenv_ret = node::LoadEnvironment(
env,
"const publicRequire ="
" require('module').createRequire(process.cwd() + '/');"
"globalThis.require = publicRequire;"
"require('vm').runInThisContext(process.argv[1]);");
if (loadenv_ret.IsEmpty()) // There has been a JS exception.
return 1;
exit_code = node::SpinEventLoop(env).FromMaybe(1);
// node::Stop() can be used to explicitly stop the event loop and keep
// further JavaScript from running. It can be called from any thread,
// and will act like worker.terminate() if called from another thread.
node::Stop(env);
}
return exit_code;
}
-->
Hi, Im trying out the C++ embedder API and one thing I'm confused about is multiple runs of a script in the same environment. In the code below (taken from the NodeJS docs) a new environment setup is created per script run, and if I'm understanding it correctly it creates its own event loop, isolate, and context. And then when we load a node environment itll take all those and execute a script within that environment. I want to be able to reduce the amount of overhead in running a script, is it possible to share this CommonEnvironmentSetup object? Can we have say, a class that creates V8, initializes node and an event loop + isolate + anything else we need and then have a method in that class that just injects the script into the environment and runs it?
-->