From afa2374e8b66795bbe6a9da02a9c7edcdac53d3f Mon Sep 17 00:00:00 2001 From: Vivek Date: Sun, 12 Jul 2026 01:08:26 +0530 Subject: [PATCH 1/3] fix: capture a dynamic import() inside a template ${} hole The module-graph edge scanner missed a dynamic import() whose string-literal specifier sits inside a template-literal ${} hole (html`${import('./widget.ts')}`). The browser-bound authorization gate and preload derive from the module graph, so that module was not admitted as a dynamic edge and 404'd if actually loaded (the admit-fewer direction of the #753 family, pre-existing on main). Root cause: parseFile scanned dynamic imports over the fully-blanked mask (redactStringsAndTemplates(src, true)), which blanks ${} hole code along with template text, so DYNAMIC_IMPORT_RE never saw the import. The static IMPORT_RE / EXPORT_FROM_RE must stay on that mask (a statement cannot appear in a hole, and the blanked mask is what closes the #753 swallow class), so only the dynamic scan moves to redactToPlaceholders, which keeps hole code readable while tokenizing string / template-text bodies and blanking comment / regex bodies. The specifier is recovered from the literals array. DYNAMIC_IMPORT_RE is tightly anchored on import( with no lazy cross-delimiter span, so this does not reopen the swallow class; a dynamic import written as literal text stays a non-edge. Closes #918 --- packages/server/AGENTS.md | 2 +- packages/server/src/module-graph.js | 29 +++++- .../test/module-graph/dynamic-import.test.js | 33 +++++++ .../import-edges-differential.test.js | 94 ++++++++++++++----- 4 files changed, 131 insertions(+), 27 deletions(-) diff --git a/packages/server/AGENTS.md b/packages/server/AGENTS.md index 9fb85bb72..a2fd5150d 100644 --- a/packages/server/AGENTS.md +++ b/packages/server/AGENTS.md @@ -77,7 +77,7 @@ with metadata, Suspense, streaming) for HTML, or `api.js` / | `stream.js` | Server-side stream-action builders (#248). `stream.append/prepend/before/after/replace/update/remove(target, content?)` compose the `` HTML (one `