◐ Shell
clean mode source ↗

module: add __esModule to require()'d ESM · nodejs/node@f9dc1ea

@@ -966,6 +966,70 @@ void ModuleWrap::CreateCachedData(const FunctionCallbackInfo<Value>& args) {

966966

}

967967

}

968968969+

// This v8::Module::ResolveModuleCallback simply links `import 'original'`

970+

// to the env->temporary_required_module_facade_original() which is stashed

971+

// right before this callback is called and will be restored as soon as

972+

// v8::Module::Instantiate() returns.

973+

MaybeLocal<Module> LinkRequireFacadeWithOriginal(

974+

Local<Context> context,

975+

Local<String> specifier,

976+

Local<FixedArray> import_attributes,

977+

Local<Module> referrer) {

978+

Environment* env = Environment::GetCurrent(context);

979+

Isolate* isolate = context->GetIsolate();

980+

CHECK(specifier->Equals(context, env->original_string()).ToChecked());

981+

CHECK(!env->temporary_required_module_facade_original.IsEmpty());

982+

return env->temporary_required_module_facade_original.Get(isolate);

983+

}

984+985+

// Wraps an existing source text module with a facade that adds

986+

// .__esModule = true to the exports.

987+

// See env->required_module_facade_source_string() for the source.

988+

void ModuleWrap::CreateRequiredModuleFacade(

989+

const FunctionCallbackInfo<Value>& args) {

990+

Isolate* isolate = args.GetIsolate();

991+

Local<Context> context = isolate->GetCurrentContext();

992+

Environment* env = Environment::GetCurrent(context);

993+

CHECK(args[0]->IsObject()); // original module

994+

Local<Object> wrap = args[0].As<Object>();

995+

ModuleWrap* original;

996+

ASSIGN_OR_RETURN_UNWRAP(&original, wrap);

997+998+

// Use the same facade source and URL to hit the compilation cache.

999+

ScriptOrigin origin(isolate,

1000+

env->required_module_facade_url_string(),

1001+

0, // line offset

1002+

0, // column offset

1003+

true, // is cross origin

1004+

-1, // script id

1005+

Local<Value>(), // source map URL

1006+

false, // is opaque (?)

1007+

false, // is WASM

1008+

true); // is ES Module

1009+

ScriptCompiler::Source source(env->required_module_facade_source_string(),

1010+

origin);

1011+1012+

// The module facade instantiation simply links `import 'original'` in the

1013+

// facade with the original module and should never fail.

1014+

Local<Module> facade =

1015+

ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();

1016+

// Stash the original module in temporary_required_module_facade_original

1017+

// for the LinkRequireFacadeWithOriginal() callback to pick it up.

1018+

CHECK(env->temporary_required_module_facade_original.IsEmpty());

1019+

env->temporary_required_module_facade_original.Reset(

1020+

isolate, original->module_.Get(isolate));

1021+

CHECK(facade->InstantiateModule(context, LinkRequireFacadeWithOriginal)

1022+

.IsJust());

1023+

env->temporary_required_module_facade_original.Reset();

1024+1025+

// The evaluation of the facade is synchronous.

1026+

Local<Value> evaluated = facade->Evaluate(context).ToLocalChecked();

1027+

CHECK(evaluated->IsPromise());

1028+

CHECK_EQ(evaluated.As<Promise>()->State(), Promise::PromiseState::kFulfilled);

1029+1030+

args.GetReturnValue().Set(facade->GetModuleNamespace());

1031+

}

1032+9691033

void ModuleWrap::CreatePerIsolateProperties(IsolateData* isolate_data,

9701034

Local<ObjectTemplate> target) {

9711035

Isolate* isolate = isolate_data->isolate();

@@ -998,6 +1062,10 @@ void ModuleWrap::CreatePerIsolateProperties(IsolateData* isolate_data,

9981062

target,

9991063

"setInitializeImportMetaObjectCallback",

10001064

SetInitializeImportMetaObjectCallback);

1065+

SetMethod(isolate,

1066+

target,

1067+

"createRequiredModuleFacade",

1068+

CreateRequiredModuleFacade);

10011069

}

1002107010031071

void ModuleWrap::CreatePerContextProperties(Local<Object> target,

@@ -1038,6 +1106,8 @@ void ModuleWrap::RegisterExternalReferences(

10381106

registry->Register(GetStatus);

10391107

registry->Register(GetError);

104011081109+

registry->Register(CreateRequiredModuleFacade);

1110+10411111

registry->Register(SetImportModuleDynamicallyCallback);

10421112

registry->Register(SetInitializeImportMetaObjectCallback);

10431113

}