Skip to content

Import scanner counts imports shown as code inside template literals #159

Description

@vivek7405

Problem

The module-graph import scanner (packages/server/src/module-graph.js, parseFile) runs IMPORT_RE / EXPORT_FROM_RE directly on raw source with no string/template redaction. So an import '...' statement that appears as TEXT inside a template literal (e.g. example code shown in a <pre> inside an html\`` template) is mistaken for a real import, creating a phantom graph edge.

Observed live on docs.webjs.dev/docs/getting-started: the page shows import '../components/counter.ts'; as example code inside its html\`template. There is no realapp/docs/components/counter.tsfile, yet the SSR emits`, which 404s.

This hits any tutorial/docs/marketing app that displays import statements as content.

Design / approach

Reuse the existing position-preserving lexer redactStringsAndTemplates from js-scan.js as a MASK. It blanks string/template CONTENT to spaces while keeping code (including the import / export / from keywords) intact at the same offsets.

Cannot run IMPORT_RE on the redacted text directly, because the import SPECIFIER is itself a string and would be blanked (real relative imports would be missed). Instead:

  1. Compute const masked = redactStringsAndTemplates(src) once.
  2. Run IMPORT_RE / EXPORT_FROM_RE on the RAW src (so the specifier capture is intact).
  3. For each match, skip it unless masked.slice(m.index, m.index + KEYWORD_LEN) still equals the keyword (import / export). A real top-level import keeps its keyword in masked; a keyword inside a template/string body is blanked, so the phantom is dropped.

This is verdict-safe for the gate and elision too: a path that only ever appears inside a string was never a real import, so dropping it is correct everywhere the graph is consumed.

Acceptance criteria

  • An import/export ... from appearing inside a template literal or string is NOT added as a graph edge
  • Real top-level relative imports (and export ... from re-exports, including multi-line) are still detected
  • The docs /app/docs/components/counter.ts phantom preload 404 is gone
  • Unit test with a fixture page that renders import './x.ts' as template text; counterfactual fails without the mask
  • Docs / AGENTS.md updated if the scanner contract wording changed

Found alongside #158 while auditing all four in-repo dogfood apps for broken modulepreload hints (blog hit #158; docs hit this; website + ui-website were clean).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions