Skip to content

fix(transforms): stop dropping import attributes on JSON modules (depends on #2999) - #3006

Merged
kwakayama merged 1 commit into
mainfrom
fix/preserve-import-attributes
Jul 22, 2026
Merged

fix(transforms): stop dropping import attributes on JSON modules (depends on #2999)#3006
kwakayama merged 1 commit into
mainfrom
fix/preserve-import-attributes

Conversation

@mattboon

Copy link
Copy Markdown
Collaborator

Summary

Found while fixing bug 5. This is a hard prerequisite for bugs 5 and 6 — neither route could even be exercised until it was fixed.

import { notFound } from "veryfront" — a documented public API — failed to load at all, 500-ing every page that used it:

Attempted to load JSON module without specifying "type": "json" attribute in the import statement.

Two compounding causes:

1. esbuild was silently dropping the attribute. Every source transform lowers to es2020/es2022, both of which pre-date import attributes, so esbuild dropped with { type: "json" } rather than erroring. The framework barrel reaches #veryfront/server/dev-ui/manifest.json, whose attribute vanished. Verified directly:

es2020                        -> import m from "…/manifest.json";
esnext                        -> import m from "…/manifest.json" with { type: "json" };
es2020 + supported override   -> import m from "…/manifest.json" with { type: "json" };

Fixed with an explicit supported: { "import-attributes": true }, shared as ESBUILD_SUPPORTED_FEATURES so every source transform agrees rather than each target: site drifting.

2. With the attribute preserved, the next failure was the opposite.

Expected a Json module, but identified a Mjs module

The framework resolver compiles a .json dependency into a cached .mjs that default-exports the data, but left the attribute — which describes the original target — in place. Attributes on imports that now point at a .mjs are stripped.

Reproduction

Test evidence

ok | 24 passed (211 steps) | 0 failed      # src/transforms/pipeline/

Covers attribute preservation on static and dynamic imports, and the strip pass (drops it for a .mjs target, keeps it for a genuine .json target, single quotes, plain imports untouched).

Wider suite: deno task test:unit2525 passed | 0 failed.

SSR evidence

Emitted framework bundle, before → after:

import devUiManifest from "#veryfront/server/dev-ui/manifest.json";
import devUiManifest from "#veryfront/server/dev-ui/manifest.json" with { type: "json" };

Route status:

/test/h-redirect    500 -> 302     # redirect() from getServerData, restored
/test/i-not-found   500 -> 404     # unblocks #3007
/test/l-error-thrown 500 -> 500    # now reaching the intended error path, unblocks #3008

Note h-redirect — the reproducer recorded redirect() as working at 0.1.1094. It had since regressed to a 500 on main; this restores it.

Client evidence

PASS /test/h-redirect
PASS /test/j-query-params?name=Grace
PASS /test/t-cookies

Related


Chain: this PR is part of a 13-PR chain fixing the bugs catalogued in
veryfront-router-testing.
Its base is the previous PR in the chain, so the diff shows only this fix.
The root of the chain is #2999 (fix/ssr-lazy-import-graceful-degrade) — merge #2999 first, then
rebase the chain onto main.

Regression gate: deno task test:unit2525 passed | 0 failed; deno task lint,
deno task fmt:check and deno task typecheck all clean. The reproducer's full 56-route
matrix (ROUTES.txt + sweep.sh) was re-run after every fix: 7 routes improved, 0 regressed.
A 46-route Chromium hydration sweep (client-sweep.mjs) backs the client-side claims.

@kwakayama kwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Score: 88/100

The implementation is small and targeted, and the tests cover both preserving JSON import attributes through esbuild and removing the stale JSON attribute after a framework JSON dependency is rewritten to .mjs.

Not merge-ready yet:

  • This is stacked on lower open PRs, including blocked/type-failing PRs.
  • The PR status rollup only shows CLA, not full CI.

Watch item: stripJsonAttributesFromModuleImports is a regex over compiled output, so correctness is coupled to esbuild output shape. That is acceptable for this narrow case, but it should stay covered if more import attributes or output formats are introduced.

@mattboon
mattboon force-pushed the fix/dynamic-import-specifier-resolution branch from 73333ce to 3ab5861 Compare July 21, 2026 19:22
@mattboon
mattboon force-pushed the fix/preserve-import-attributes branch from aacf9b5 to 85ab840 Compare July 21, 2026 19:22
@mattboon
mattboon force-pushed the fix/dynamic-import-specifier-resolution branch from 3ab5861 to a3d1c39 Compare July 21, 2026 19:44
@mattboon
mattboon force-pushed the fix/preserve-import-attributes branch from 85ab840 to 2487d05 Compare July 21, 2026 19:44
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from 2487d05 to dcb6367 Compare July 21, 2026 20:30
@kwakayama
kwakayama force-pushed the fix/dynamic-import-specifier-resolution branch from a3d1c39 to a605762 Compare July 21, 2026 20:30
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from dcb6367 to aa8a5e7 Compare July 21, 2026 20:38
@kwakayama
kwakayama force-pushed the fix/dynamic-import-specifier-resolution branch from a605762 to b744d20 Compare July 21, 2026 20:38
kwakayama
kwakayama previously approved these changes Jul 21, 2026

@kwakayama kwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up approval after #2999 merged and the stack was rebased onto main.

Score: 92/100.

Rationale: import-attribute preservation is scoped and the rebased stack regression suite stayed green.

Next step: merge after lower stack PRs and refreshed checks are green.

@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from 1444152 to eb196d5 Compare July 21, 2026 22:39
@kwakayama
kwakayama force-pushed the fix/dynamic-import-specifier-resolution branch from 1987423 to 783af4a Compare July 21, 2026 22:39
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from eb196d5 to d9b21fb Compare July 21, 2026 22:47
@kwakayama
kwakayama force-pushed the fix/dynamic-import-specifier-resolution branch from 783af4a to 34af0c0 Compare July 21, 2026 22:47
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from d9b21fb to 4c2bb62 Compare July 21, 2026 22:57
@kwakayama
kwakayama force-pushed the fix/dynamic-import-specifier-resolution branch from 34af0c0 to 33e3873 Compare July 21, 2026 22:57
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from 4c2bb62 to bbf0a11 Compare July 21, 2026 23:38
@kwakayama
kwakayama force-pushed the fix/dynamic-import-specifier-resolution branch 2 times, most recently from 56e5007 to f85d6cf Compare July 21, 2026 23:44
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from bbf0a11 to 391d2ff Compare July 21, 2026 23:44
@kwakayama
kwakayama force-pushed the fix/dynamic-import-specifier-resolution branch from f85d6cf to d6c07ca Compare July 21, 2026 23:53
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from 391d2ff to 276b1fd Compare July 21, 2026 23:53
Base automatically changed from fix/dynamic-import-specifier-resolution to main July 22, 2026 00:14
@kojiwakayama
kojiwakayama dismissed kwakayama’s stale review July 22, 2026 00:14

The base branch was changed.

@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from 276b1fd to 03a1d2c Compare July 22, 2026 00:15
kwakayama
kwakayama previously approved these changes Jul 22, 2026

@kwakayama kwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up approval after #3005 merged and #3006 was rebased onto main.

Score: 93/100.

Rationale: the transform preserves import attributes for JSON modules without widening unrelated import rewriting behavior, and focused regression coverage still passes after the rebase.

Verification:

  • deno task audit
  • combined targeted regression suite: 21 tests, 334 steps, 0 failed

Next step: wait for refreshed GitHub checks and required reviewer gate, then merge when green.

Constraint: JSON module imports require their `with { type: "json" }` attribute at runtime, even when source is lowered to older JavaScript targets.
Rejected: Raising the sanitizer opt-out baseline | tests can stop the shared esbuild service instead of disabling leak checks.
Confidence: high
Scope-risk: narrow
Directive: Keep import-attribute support centralized in shared esbuild transform options.
Tested: deno test --allow-all src/transforms/pipeline/stages/compile.test.ts
Tested: deno task lint:sanitizer-baseline
Tested: deno task lint
Tested: targeted regression suite: 18 tests, 303 steps, 0 failed
Tested: deno task audit
Not-tested: manual production deploy
@kwakayama
kwakayama force-pushed the fix/preserve-import-attributes branch from 03a1d2c to 69d29b9 Compare July 22, 2026 00:22

@kwakayama kwakayama left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up approval after fixing the sanitizer ratchet on the rebased #3006 head.

Score: 93/100.

Rationale: import attributes remain preserved, and the test now closes the esbuild service instead of adding sanitizer opt-outs.

Verification:

  • deno test --allow-all src/transforms/pipeline/stages/compile.test.ts
  • deno task lint:sanitizer-baseline
  • deno task lint
  • targeted regression suite: 18 tests, 303 steps, 0 failed
  • deno task audit

Next step: wait for refreshed GitHub checks and required reviewer gate, then merge when green.

@kwakayama
kwakayama merged commit 1e85b5e into main Jul 22, 2026
28 checks passed
@kwakayama
kwakayama deleted the fix/preserve-import-attributes branch July 22, 2026 00:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants