fix(javascript): keep string Worker paths unresolved without a document base (#3797)

A plain new Worker("./w.js") or navigator.serviceWorker.register("./sw.js")
resolves against the document base URL in a browser, and a Node
worker_threads string resolves against the working directory. Static
analysis was resolving browser strings against the calling script, which
recorded a resolved mapping to the wrong file.

Only new Worker(new URL(path, import.meta.url)) now produces a specifier.
Other worker and service-worker strings keep their expression and stay
unresolved, matching the existing worker_threads string handling.

Fixes #3309

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822andClaude Opus 5.5 authored and GitHub committed 2026-10-14 19:13:17 -07:00
1 parent 7a66470385
commit af6a998066
9 files changed
+119 -51

No files matched your search

@@ -95,19 +95,25 @@ export const inspectCall = (
addReference(context, {
node,
kind: "worker",
// Node string paths use the process cwd or filesystem root, neither of
// which is established by the analyzed source's artifact location.
// A string path is relative to the document base URL in a browser and
// to the process cwd in Node; the analyzed source's artifact location
// establishes neither. Only `new URL(path, import.meta.url)` names a
// location relative to this module.
specifier:
(workerConstructor === "node" ? undefined : first) ??
(workerConstructor === undefined || worker === undefined
workerConstructor === undefined || worker === undefined
? undefined
: workerUrlSpecifier(worker, bindings)),
: workerUrlSpecifier(worker, bindings),
});
// Service worker script URLs are also relative to the document base URL.
if (
name === "serviceWorker.register" ||
name.endsWith(".serviceWorker.register")
)
addReference(context, { node, kind: "service-worker", specifier: first });
addReference(context, {
node,
kind: "service-worker",
specifier: undefined,
});
inspectEndpointCall(node, name, first, context);
inspectStorageCall(node, name, first, context);
if (first === "audio" || first === "video")