Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embedder API: Loading ES6 Modules #3991

Closed
DavidPeicho opened this issue Oct 11, 2022 · 5 comments
Closed

Embedder API: Loading ES6 Modules #3991

DavidPeicho opened this issue Oct 11, 2022 · 5 comments
Labels

Comments

@DavidPeicho
Copy link

DavidPeicho commented Oct 11, 2022

Details

I am trying to use the NodeJS Embedder API in a C++ application. My goal would be to load JS modules that might contain import statement. What would be the best way to go about that?

So far, I have created a v8::Module and I can instantiate it and run it without trouble. However, I have issue importing modules especially default ones such as path. I am not sure what would be the best way to resolve module recursively taking into account the internal modules nodejs exposes (path, http, etc...)

What would be the best way to achieve something like that?

Node.js version

v18.10.0

Example code

Example with custom module execution:

v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate,
    "import Path from 'path';console.log(Path);"
).ToLocalChecked();

v8::ScriptOrigin origin(isolate, v8::String::NewFromUtf8(isolate, "main.mjs").ToLocalChecked(),
        0,
        0,
        false,
        0,
        v8::Local<v8::Value>(),
        false,
        false,
        true
);
v8::ScriptCompiler::Source source(source, origin);
v8::Local<v8::Module> module;
if (!v8::ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
    return;
}

module->InstantiateModule(context, [](
    v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
    v8::Local<v8::FixedArray> import_assertions, v8::Local<v8::Module> referrer) {
    // How should the module be resolved? Can we use the ModuleWrapper from NodeJS?
    return v8::Local<v8::Module>();
});

Operating system

MacOS Monterey 12.6, but not that relevant for this particular question

Scope

Embedder API

Module and version

Not applicable.

@DavidPeicho
Copy link
Author

DavidPeicho commented Oct 18, 2022

I tried a lot of ways, none of them worked so far.

1. SourceTextModule

I tried to use vm.SourceTextModule, but it looks like I would need to link myself the modules dependencies...

2. vm.runInThisContext + dynamic import

Environment is loaded using a custom callback:

v8::MaybeLocal<v8::Value> loadRes = node::LoadEnvironment(env,
    [this](const node::StartExecutionCallbackInfo& info) {
        ...
    });

And then I use the vm.runInThisContext function obtained during the environment setup:

v8::Local<v8::Value> source = v8::String::NewFromUtf8Literal(isolate, "import('path').then(p => console.log(p))");
runInContextFunc->Get(isolate)->Call(context, v8::Null(solate), 1, &source).ToLocalChecked();

This doesn't work and keep throwing an error: ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING. Looking at the code, it makes sense why this error is thrown. However, I am not sure what I am supposed to do. Ideally, I would like to re-use the node resolution algorithm already there.

3. LoadEnvironment without any callback

I tried to set a startup script to process.argv[1], and then load the environment using:

node::LoadEnvironment(_setup->env(), node::StartExecutionCallback{});

The script is executed properly, but I still can't easily use import statements outside of that.

@DavidPeicho
Copy link
Author

I don't know if it's the best idea, but I solved that using evalModule from the internals.

@MadLittleMods
Copy link

I tried to use vm.SourceTextModule, but it looks like I would need to link myself the modules dependencies...

Related to nodejs/node#31234 to provide built-in implementations of module linker, initializeImportMeta, importModuleDynamically

Copy link

There has been no activity on this issue for 11 months. The help repository works best when sustained engagement moves conversation forward. The issue will be closed in 1 month. If you are still experiencing this issue on the latest supported versions of Node.js, please leave a comment.

@github-actions github-actions bot added the stale label Mar 18, 2024
Copy link

Closing after no activity on this issue for 12 months.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants