Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would one enable and use ES6 modules in the V8 javascript engine?

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.

like image 835
Boinst Avatar asked Aug 26 '18 04:08

Boinst


People also ask

How to enable ES6 modules in Node JS?

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.

What is the use of import in ES6?

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.

How to use the ESM module in JavaScript?

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.

What are the new features in ES6?

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...


1 Answers

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.
}
like image 187
snek Avatar answered Oct 01 '22 21:10

snek