I use an embedded V8 engine in my (Windows Desktop) C++ application. I understand that V8 has support for ES6 modules. How would I go about activating and using this feature in my application?
I would not expect anyone to have a complete worked example of how this works, but a high level answer pointing me (and future readers) in the right direction would entirely fulfil my hopes and aspirations for this question.
Node has experimental support for ES modules. To enable them we need to make some changes to the package.json file. Before following the steps make sure that Node is installed. Below are the steps to achieve the same. In the package.json file add “type” : “module”. Adding this enables ES6 modules.
Introduction to ES6 import: The import statement is used to import modules that are exported by some other module. A module is a file that contains a piece of reusable code. The import modules are in strict mode whether it is declared or not.
Another way to use the esm module is by creating another file say server.js that loads esm before the actual application. In the server.js file write the below code Note: In the file server.js, we are importing the index.js file which holds the actual program which needs to be executed.
New Features in ES6 1 The let keyword 2 The const keyword 3 JavaScript Arrow Functions 4 JavaScript For/of 5 JavaScript Map Objects 6 JavaScript Set Objects 7 JavaScript Classes 8 JavaScript Promises 9 JavaScript Symbol 10 Default Parameters More items...
In leiu of actual examples from V8 (I was actually planning to write some at some point), I will write one here. For some examples of use in the wild I recommend Node.js's implementation, or my own, both using very similar layouts (having been written by the same people). There is also an implementation in D8, V8's CLI debugger.
Local<String> source_text = String::NewFromUtf8(
isolate, "import 'some thing'; 1 + 1");
ScriptOrigin origin(String::NewFromUtf8("main.mjs"), // specifier
Integer::New(isolate, 0), // line offset
Integer::New(isolate, 0), // column offset
False(isolate), // is cross origin
Local<Integer>(), // script id
Local<Value>(), // source map URL
False(isolate), // is opaque
False(isolate), // is WASM
True(isolate)); // is ES6 module
Context::Scope context_scope(context);
ScriptCompiler::Source source(source_text, origin);
Local<Module> module;
if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
// if you have a v8::TryCatch, you should check it here.
return;
}
// You can resolve import requests ahead of time (useful for async)
for (int i = 0; i < module->GetModuleRequestsLength(); i++) {
Local<String> specifier = module->GetModuleRequest(i); // "some thing"
}
// or you can resolve them sync in the InstantiateModule callback
module->InstantiateModule(context, [](Local<Context> context, // "main.mjs"
Local<String> specifier, // "some thing"
Local<Module> referrer) {
return Local<Module>();
});
// setting this callback enables dynamic import
isolate->SetImportModuleDynamicallyCallback([](Local<Context> context,
Local<ScriptOrModule> referrer,
Local<String> specifier) {
return MaybeLocal<Promise>();
});
// setting this callback enables import.meta
isolate->SetHostInitializeImportMetaObjectCallback([](Local<Context> context,
Local<Module> module,
Local<Object> meta) {
// meta->Set(key, value); you could set import.meta.url here
});
Local<Value> result;
if (module->Evaluate(context).ToLocal(&result)) {
String::Utf8Value utf8(isolate, result);
printf("module eval result: %s\n", *utf8);
} else {
// once again, if you have a v8::TryCatch, use it here.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With