Skip to content

Commit 77c49c5

Browse files
aduh95RafaelGSS
authored andcommitted
esm: avoid import.meta setup costs for unused properties
PR-URL: #57286 Reviewed-By: Jacob Smith <[email protected]> Reviewed-By: Edy Silva <[email protected]>
1 parent 429b4ee commit 77c49c5

File tree

3 files changed

+82
-7
lines changed

3 files changed

+82
-7
lines changed

lib/internal/modules/esm/initialize_import_meta.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ const {
55
} = primordials;
66

77
const { getOptionValue } = require('internal/options');
8-
const { fileURLToPath } = require('internal/url');
9-
const { dirname } = require('path');
8+
const {
9+
setLazyPathHelpers,
10+
} = internalBinding('modules');
11+
1012
const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta-resolve');
1113

1214
/**
@@ -58,11 +60,9 @@ function initializeImportMeta(meta, context, loader) {
5860

5961
// Alphabetical
6062
if (StringPrototypeStartsWith(url, 'file:') === true) {
61-
// These only make sense for locally loaded modules,
62-
// i.e. network modules are not supported.
63-
const filePath = fileURLToPath(url);
64-
meta.dirname = dirname(filePath);
65-
meta.filename = filePath;
63+
// dirname
64+
// filename
65+
setLazyPathHelpers(meta, url);
6666
}
6767

6868
if (!loader || loader.allowImportMetaResolve) {

src/env_properties.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
V(destroyed_string, "destroyed") \
126126
V(detached_string, "detached") \
127127
V(dh_string, "DH") \
128+
V(dirname_string, "dirname") \
128129
V(divisor_length_string, "divisorLength") \
129130
V(dns_a_string, "A") \
130131
V(dns_aaaa_string, "AAAA") \
@@ -335,6 +336,7 @@
335336
"export * from 'original'; export { default } from 'original'; export " \
336337
"const __esModule = true;") \
337338
V(require_string, "require") \
339+
V(resolve_string, "resolve") \
338340
V(resource_string, "resource") \
339341
V(result_string, "result") \
340342
V(retry_string, "retry") \

src/node_modules.cc

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ using v8::Null;
3535
using v8::Object;
3636
using v8::ObjectTemplate;
3737
using v8::Primitive;
38+
using v8::PropertyCallbackInfo;
3839
using v8::String;
3940
using v8::Undefined;
4041
using v8::Value;
@@ -594,6 +595,76 @@ void GetCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
594595
isolate, v8::Null(isolate), names.data(), values.data(), names.size()));
595596
}
596597

598+
static void PathHelpersLazyGetter(Local<v8::Name> name,
599+
const PropertyCallbackInfo<Value>& info) {
600+
Isolate* isolate = info.GetIsolate();
601+
// This getter has no JavaScript function representation and is not
602+
// invoked in the creation context.
603+
// When this getter is invoked in a vm context, the `Realm::GetCurrent(info)`
604+
// returns a nullptr and retrieve the creation context via `this` object and
605+
// get the creation Realm.
606+
Local<Value> receiver_val = info.This();
607+
if (!receiver_val->IsObject()) {
608+
THROW_ERR_INVALID_INVOCATION(isolate);
609+
return;
610+
}
611+
Local<Object> receiver = receiver_val.As<Object>();
612+
Local<Context> context;
613+
if (!receiver->GetCreationContext().ToLocal(&context)) {
614+
THROW_ERR_INVALID_INVOCATION(isolate);
615+
return;
616+
}
617+
Environment* env = Environment::GetCurrent(context);
618+
619+
node::Utf8Value url(isolate, info.Data());
620+
auto file_url = ada::parse(url.ToStringView());
621+
CHECK(file_url);
622+
auto file_path = url::FileURLToPath(env, *file_url);
623+
CHECK(file_path.has_value());
624+
std::string_view ret_view = file_path.value();
625+
626+
node::Utf8Value utf8name(isolate, name);
627+
auto plain_name = utf8name.ToStringView();
628+
if (plain_name == "dirname") {
629+
#ifdef _WIN32
630+
#define PATH_SEPARATOR '\\'
631+
#else
632+
#define PATH_SEPARATOR '/'
633+
#endif
634+
auto index = ret_view.rfind(PATH_SEPARATOR);
635+
CHECK(index != std::string_view::npos);
636+
ret_view.remove_suffix(ret_view.size() - index);
637+
#undef PATH_SEPARATOR
638+
}
639+
Local<Value> ret;
640+
if (!ToV8Value(context, ret_view, isolate).ToLocal(&ret)) {
641+
return;
642+
}
643+
info.GetReturnValue().Set(ret);
644+
}
645+
void InitImportMetaPathHelpers(const FunctionCallbackInfo<Value>& args) {
646+
// target, url, shouldSetDirnameAndFilename, resolve
647+
CHECK_GE(args.Length(), 2);
648+
CHECK(args[0]->IsObject());
649+
CHECK(args[1]->IsString());
650+
651+
Isolate* isolate = args.GetIsolate();
652+
Local<Context> context = isolate->GetCurrentContext();
653+
Environment* env = Environment::GetCurrent(context);
654+
655+
auto target = args[0].As<Object>();
656+
657+
// N.B.: Order is important to keep keys in alphabetical order.
658+
if (target
659+
->SetLazyDataProperty(
660+
context, env->dirname_string(), PathHelpersLazyGetter, args[1])
661+
.IsNothing() ||
662+
target
663+
->SetLazyDataProperty(
664+
context, env->filename_string(), PathHelpersLazyGetter, args[1])
665+
.IsNothing())
666+
return;
667+
}
597668
void SaveCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
598669
Isolate* isolate = args.GetIsolate();
599670
Local<Context> context = isolate->GetCurrentContext();
@@ -627,6 +698,7 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
627698
SetMethod(isolate, target, "flushCompileCache", FlushCompileCache);
628699
SetMethod(isolate, target, "getCompileCacheEntry", GetCompileCacheEntry);
629700
SetMethod(isolate, target, "saveCompileCacheEntry", SaveCompileCacheEntry);
701+
SetMethod(isolate, target, "setLazyPathHelpers", InitImportMetaPathHelpers);
630702
}
631703

632704
void BindingData::CreatePerContextProperties(Local<Object> target,
@@ -682,6 +754,7 @@ void BindingData::RegisterExternalReferences(
682754
registry->Register(FlushCompileCache);
683755
registry->Register(GetCompileCacheEntry);
684756
registry->Register(SaveCompileCacheEntry);
757+
registry->Register(InitImportMetaPathHelpers);
685758
}
686759

687760
} // namespace modules

0 commit comments

Comments
 (0)