Search code examples
c++v8embedded-v8

Default export for synthetic module in V8


I want to use default export with synthetic module in V8. I have synthetic_module, a module which exposes C++ functions to JS, and code like the following:

Local<String> txt = String::NewFromUtf8(isolate, u8R"(
  import defaultFoo from './myModule.js';
  defaultFoo();
").ToLocalChecked();

...

ScriptCompiler::Source src(txt, origin);
static Local<Module> module
  = ScriptCompiler::CompileModule(isolate, &src).ToLocalChecked();

// module->GetStatus() is kUninstantiated here

module->InstantiateModule(context,
  [](Local<Context> context,
     Local<String> specifier,
     Local<Module> referrer) -> MaybeLocal<Module> {
       return synthetic_module;
  });

// module->GetStatus() is still kUninstantiated
// if synthetic_module does not have default export

Using v8::TryCatch, I can get a SyntaxError that synthetic_module does not have default export. Is there a way to set default export when using synthetic module in V8? Thanks for your answer in advance.


Solution

  • The hint was in the error message. The error message was:

    SyntaxError: The requested module './myModule.js' does not provide an export named 'default'
    

    Therefore, to set the default export, I can just make a export with name "default" like this.

    Local<Module> synthetic_module
      = Module::CreateSyntheticModule(
          isolate,
          String::NewFromUtf8(isolate, "Synthetic").ToLocalChecked(),
          { String::NewFromUtf8(isolate, "default").ToLocalChecked(), ... },
          [](Local<Context> context, Local<Module> module) -> MaybeLocal<Value> {
            auto isolate = context->GetIsolate();
            module->SetSyntheticModuleExport(
              String::NewFromUtf8(isolate, "default").ToLocalChecked(),
              Function::New(context, ...)
            );
            return MaybeLocal<Value>(True(isolate));
          }
        );