Skip to content

Commit 11594e3

Browse files
committed
read file on cpp side if code is not available. if neither cjs nor esm
1 parent e5075cb commit 11594e3

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

lib/internal/modules/esm/get_format.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ function underNodeModules(url) {
9090
*/
9191
function detectModuleFormat(source, url) {
9292
try {
93-
return containsModuleSyntax(source ?? readFileSync(url, 'utf8'), fileURLToPath(url), url) ? 'module' : 'commonjs';
93+
return containsModuleSyntax(source, fileURLToPath(url), url) ? 'module' : 'commonjs';
9494
} catch {
95+
// containsModuleSyntax throws if source is undefined and the passed filename cannot be read
9596
return 'commonjs';
9697
}
9798
}

src/node_contextify.cc

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,14 +1705,32 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo<Value>& args) {
17051705

17061706
CHECK_GE(args.Length(), 2);
17071707

1708-
// Argument 1: source code
1709-
CHECK(args[0]->IsString());
1710-
Local<String> code = args[0].As<String>();
1711-
17121708
// Argument 2: filename
17131709
CHECK(args[1]->IsString());
17141710
Local<String> filename = args[1].As<String>();
17151711

1712+
// Argument 1: source code; if undefined, read from filename in argument 2
1713+
Local<String> code;
1714+
if (args[0]->IsUndefined()) {
1715+
CHECK(!filename.IsEmpty());
1716+
const char* filename_str = Utf8Value(isolate, filename).out();
1717+
std::string contents;
1718+
int result = ReadFileSync(&contents, filename_str);
1719+
if (result != 0) {
1720+
isolate->ThrowException(
1721+
ERR_MODULE_NOT_FOUND(isolate, "Cannot read file %s", filename_str));
1722+
return;
1723+
}
1724+
code = String::NewFromUtf8(isolate,
1725+
contents.c_str(),
1726+
v8::NewStringType::kNormal,
1727+
contents.length())
1728+
.ToLocalChecked();
1729+
} else {
1730+
CHECK(args[0]->IsString());
1731+
code = args[0].As<String>();
1732+
}
1733+
17161734
// Argument 3: resource name (URL for ES module).
17171735
Local<String> resource_name = filename;
17181736
if (args[2]->IsString()) {
@@ -1729,6 +1747,7 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo<Value>& args) {
17291747
Local<Function> fn;
17301748
TryCatchScope try_catch(env);
17311749
ShouldNotAbortOnUncaughtScope no_abort_scope(env);
1750+
17321751
if (CompileFunctionForCJSLoader(
17331752
env, context, code, filename, &cache_rejected, cjs_var)
17341753
.ToLocal(&fn)) {
@@ -1740,7 +1759,12 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo<Value>& args) {
17401759
}
17411760

17421761
bool result = ShouldRetryAsESM(realm, message, code, resource_name);
1743-
args.GetReturnValue().Set(result);
1762+
if (result) { // successfully parsed as ESM after failing to parse as CJS => ESM syntax
1763+
args.GetReturnValue().Set(result);
1764+
return;
1765+
}
1766+
1767+
args.GetReturnValue().SetUndefined();
17441768
}
17451769

17461770
static void StartSigintWatchdog(const FunctionCallbackInfo<Value>& args) {

0 commit comments

Comments
 (0)