-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
module: resolve format for all situations with auto module detection on #53044
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c681f57
bd945b6
47def79
3b93cf3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1705,14 +1705,33 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo<Value>& args) { | |
|
||
CHECK_GE(args.Length(), 2); | ||
|
||
// Argument 1: source code | ||
CHECK(args[0]->IsString()); | ||
Local<String> code = args[0].As<String>(); | ||
|
||
// Argument 2: filename | ||
CHECK(args[1]->IsString()); | ||
Local<String> filename = args[1].As<String>(); | ||
|
||
// Argument 1: source code; if undefined, read from filename in argument 2 | ||
Local<String> code; | ||
if (args[0]->IsUndefined()) { | ||
CHECK(!filename.IsEmpty()); | ||
Utf8Value utf8Value(isolate, filename); | ||
const char* filename_str = utf8Value.out(); | ||
std::string contents; | ||
int result = ReadFileSync(&contents, filename_str); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reading from disk from the native layer here doesn’t seem right - it’s not guaranteed that this is on disk and at a location pointed to by filename (the filename can be some artificial ID). The JS land should be refactored to only call this after source code is confirmed instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this comes as part of the trials to cover the module type resolution for the Additionally we call this from managed code here. I am guessing that at this stage the fileUrl was already validated but that is at this stage just an assumption. This test made me think that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The exception would be surprising for a hook - resolve shouldn't be poking into the file system, that should be load's job. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that is changed now, the comment above is obsolete. The function would return undefined on file access errors. But I am still looking for a way to remove this file access without losing the test. |
||
if (result != 0) { | ||
// error reading file and no source available => undefined | ||
args.GetReturnValue().SetUndefined(); | ||
return; | ||
} | ||
code = String::NewFromUtf8(isolate, | ||
contents.c_str(), | ||
v8::NewStringType::kNormal, | ||
contents.length()) | ||
.ToLocalChecked(); | ||
} else { | ||
CHECK(args[0]->IsString()); | ||
code = args[0].As<String>(); | ||
} | ||
|
||
// Argument 3: resource name (URL for ES module). | ||
Local<String> resource_name = filename; | ||
if (args[2]->IsString()) { | ||
|
@@ -1729,6 +1748,7 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo<Value>& args) { | |
Local<Function> fn; | ||
TryCatchScope try_catch(env); | ||
ShouldNotAbortOnUncaughtScope no_abort_scope(env); | ||
|
||
if (CompileFunctionForCJSLoader( | ||
env, context, code, filename, &cache_rejected, cjs_var) | ||
.ToLocal(&fn)) { | ||
|
@@ -1740,7 +1760,13 @@ static void ContainsModuleSyntax(const FunctionCallbackInfo<Value>& args) { | |
} | ||
|
||
bool result = ShouldRetryAsESM(realm, message, code, resource_name); | ||
args.GetReturnValue().Set(result); | ||
if (result) { | ||
// successfully parsed as ESM after failing to parse as CJS => ESM syntax | ||
args.GetReturnValue().Set(result); | ||
return; | ||
} | ||
|
||
args.GetReturnValue().SetUndefined(); | ||
} | ||
|
||
static void StartSigintWatchdog(const FunctionCallbackInfo<Value>& args) { | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { writeSync } from "node:fs"; | ||
|
||
export async function resolve(specifier, context, next) { | ||
const result = await next(specifier, context); | ||
if (specifier.startsWith("file://")) { | ||
writeSync(1, `Resolved format: ${result.format}\n`); | ||
} | ||
return result; | ||
} | ||
|
||
export async function load(url, context, next) { | ||
const output = await next(url, context); | ||
writeSync(1, `Loaded original format: ${output.format}\n`); | ||
|
||
let source = `${output.source}` | ||
|
||
// This is a very incomplete and naively done implementation for testing purposes only | ||
if (source?.includes('export default')) { | ||
source = source.replace('export default', 'module.exports ='); | ||
|
||
source += '\nconsole.log(`Evaluated format: ${this === undefined ? "module" : "commonjs"}`);'; | ||
|
||
output.source = source; | ||
output.format = 'commonjs'; | ||
} | ||
|
||
return output; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import "./does-not-exist.js"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
'use strict'; | ||
const { readFile, __fromLoader } = require('fs'); | ||
const assert = require('assert'); | ||
|
||
assert.throws(() => require('./test-esm-ok.mjs'), { code: 'ERR_REQUIRE_ESM' }); | ||
|
||
assert(readFile); | ||
assert(__fromLoader); |
Uh oh!
There was an error while loading. Please reload this page.