Commit Graph

1925 Commits

Author SHA1 Message Date
Yunfei He ae43973395 perf(routing): cache app-route-graph directory reads — 5000-route build −32% (#2389)
discoverInheritedParallelSlots reads every ancestor directory of each route with fs.readdirSync to find @slot dirs. Because routes share ancestors, a directory with N sibling routes is read once per descendant route, making the scan super-linear in route-directory width. Memoize the reads in a per-scan WeakMap<matcher, Map<dir, Dirent[]>> (same pattern as findFileProbeCache/findSlotSubPagesCache), scoped to one scan so it's collected afterwards. On a 10k-route fixture this cuts build wall time ~52% (~86s -> ~42s) and syscall time ~61%, output byte-identical.
2026-06-28 19:52:11 +01:00
Nathan Nguyen 9382007bce test(perf): pin benchmark validator repository in fork CI (#2387)
Benchmark validator tests mock GitHub API paths for cloudflare/vinext, but fork CI sets GITHUB_REPOSITORY to the fork owner.

Pin the spawned validator process to cloudflare/vinext so the test remains hermetic across upstream and fork push runs.
2026-06-28 16:51:31 +01:00
James Anderson da086c0d65 Revert flaky "fix(link): start viewport prefetches immediately" (#2386)
This reverts commit 06775d3694.
2026-06-27 00:23:40 +01:00
James Anderson 13c093926c fix(test): stop autoscroll fixture servers correctly (#2384) 2026-06-26 23:03:46 +01:00
James Anderson 1593d4ce93 fix(app-router): scroll past existing hoisted styles (#2356)
* fix(app-router): scroll past existing hoisted styles

* test(app-router): restore document descriptor
2026-06-26 21:46:01 +01:00
James Anderson 9faa43e148 fix(app-router): include page segment in flight state (#2359)
* fix(app-router): include page segment in flight state

* fix(app-router): keep page marker internal
2026-06-26 21:44:20 +01:00
James Anderson a21667fd09 fix(app-router): discover nested leaf slot routes (#2350)
* fix(app-router): discover nested leaf slot routes

* test(routing): align nested leaf slot expectation

* test(routing): assert nested leaf route match

* fix(app-router): scope nested leaf slot discovery
2026-06-26 21:42:15 +01:00
James Anderson cab6622ce8 fix(app-router): restore intercepted history slots (#2363)
* fix(app-router): restore intercepted history slots

* fix(app-router): scope interception restore proof
2026-06-26 21:41:12 +01:00
James Anderson 7cad67080e fix(server): restore client trace metadata parity (#2371)
* fix(server): restore client trace metadata parity

* fix(server): use recorded spans for trace metadata

* test(server): cover active trace metadata spans

* fix(server): fail open for trace metadata propagation

* docs(server): clarify trace metadata lifecycle
2026-06-26 21:40:19 +01:00
James Anderson 4edd1e1b1c fix(css): support namespace CSS Module imports (#2345)
* fix(css): support namespace CSS Module imports

* fix(css): preserve CSS Module query semantics

* fix(css): parse JavaScript components as JSX

* fix(css): harden CSS Module import compatibility

* fix(css): order compiled MDX compatibility last
2026-06-26 21:39:12 +01:00
James Anderson 06775d3694 fix(link): start viewport prefetches immediately (#2229)
* fix(link): start viewport prefetches immediately

* fix(navigation): skip client prefetches for bots
2026-06-26 20:38:28 +00:00
James Anderson 737532aaa8 fix(app-router): preserve interception across middleware rewrites (#2342) 2026-06-26 21:36:48 +01:00
James Anderson e4f5a0e56b fix(app-router): honor global not found opt-in (#2340)
* fix(app-router): honor global not found opt-in

* fix(app-router): render default global 404 standalone

* test(app-router): avoid fixture workspace lockfile entry

* test(app-router): keep fixture esm outside workspace

* fix(app-router): add default global 404 shell

* test(app-router): cover client not found boundary

* fix(app-router): gate global not found discovery
2026-06-26 21:34:25 +01:00
James Anderson 5c1e870ace fix(router): honor middleware app rewrites for page links (#2339)
* fix(router): honor middleware app rewrites for page links

* fix(router): preserve masked page data targets

* fix(router): keep non-middleware data fetch timing

* docs(router): explain middleware data handoff invariants
2026-06-26 21:33:23 +01:00
James Anderson 0c18c9f20a fix(app-router): replay prerendered preload headers (#2333)
* fix(app-router): replay prerendered preload headers

* fix(app-router): retain preload headers during ISR

* fix(app-router): reuse ISR font preload snapshot
2026-06-26 21:32:22 +01:00
James Anderson 859a0aac15 fix(app-router): bind layout-only children defaults (#2335)
* fix(app-router): bind layout-only children defaults

* fix(app-router): preserve standalone slot owners

* fix(app-router): ghost fallback catch-all owners
2026-06-26 21:31:02 +01:00
James Anderson 592a50b76d fix(test): pin deploy suite init to node (#2383) 2026-06-26 20:26:04 +00:00
James Anderson 50e2385986 fix(form): match Next.js navigation parity (#2245)
* fix(form): match Next.js navigation parity

* fix(form): block dangerous navigation schemes

* fix(form): address Pages navigation review

* fix(form): preserve native and hard navigation fallbacks
2026-06-26 19:56:06 +00:00
James Anderson 70c500bf65 fix(app-router): scope static params across parallel routes (#2317)
* fix(app-router): scope static params across parallel routes

* fix(app-router): collect static params from parallel layouts

* style(app-router): format parallel route fixtures

* fix(app-router): scope parallel segment params
2026-06-26 20:52:20 +01:00
James Anderson feb27e8422 fix(client): isolate Pages Router module graph (#2380)
* fix(client): isolate Pages Router module graph

* fix(client): trim hybrid route ownership graph

* fix(router): preserve document-only hard navigation
2026-06-26 20:52:13 +01:00
James Anderson 4bc2dd3235 fix(image): match App Router deploy parity (#2310)
* fix(image): restore app router deploy parity

* test(image): expect configured optimizer widths

* fix(image): match responsive width selection
2026-06-26 20:36:27 +01:00
James Anderson c5bd7b33c2 fix(app-router): skip prefetches for bots (#2323)
* fix(app-router): skip prefetches for bots

* fix(link): scope bot suppression to app prefetch

* fix(app-router): skip form prefetches for bots
2026-06-26 19:59:29 +01:00
James Anderson 77d67a98c4 fix(cache): bypass unstable cache in draft mode (#2319)
* fix(cache): bypass unstable cache in draft mode

* fix(cache): preserve draft state during action rerenders
2026-06-26 19:58:36 +01:00
James Anderson 89036154cc fix(pages-router): unify client asset bootstrap (#2378)
* fix(pages-router): hydrate worker-backed dev pages

* refactor(pages-router): unify client asset bootstrap

* fix(app): preinitialize bootstrap dependencies

* test(app): distinguish preinit scripts from bootstrap

* fix(app): root-anchor bootstrap preinit modules

* test(app): cover bootstrap preinitialization in browsers

* fix(app): share client assets with nested SSR modules

* test(app): verify bootstrap preinit CSP nonces

* test(app): serve CSP nonce in worker fixture

* fix(test): read CSP script nonce property

* fix(cloudflare): emit client assets beside final workers

* fix(build): resolve pages client assets from source

* fix(app): register client assets in ssr graph

* fix(pages-router): harden client bootstrap resolution

* fix(build): emit client assets for node outputs

* fix(build): package client assets in standalone output

* test(app): reference worker nonce fixture explicitly

* fix(build): preserve client assets across environments

* refactor(build): unify client asset outputs

* fix(build): stabilize custom client asset outputs

* fix(build): finalize client assets after app builds

* fix(build): reuse client assets in hybrid builds

* fix(build): scope hybrid client assets metadata

* test(e2e): colocate Cloudflare worker fixture
2026-06-26 19:48:26 +01:00
James Anderson 41185327f3 fix(cli): respect Vite dev server config (#2379)
* fix(cli): respect Vite dev server config

* docs(cli): clarify Vite config hook ordering
2026-06-26 18:46:25 +01:00
James Anderson 25a3c26f7a feat(init): scaffold for cloudflare and node (#2279)
* feat(init): select deployment platform

* refactor(init): AST-update deployment config

* feat(init): configure Cloudflare cache and images

* fix(init): avoid backtracking in config updates

* fix(init): cover packaged Cloudflare setup

* ci: allow Cloudflare init smoke builds

* ci: fix packaged Cloudflare dependency install

* test(e2e): isolate browser fixture servers

* chore: allow Windows taskkill binary

* fix(init): configure Cloudflare image adapter

* fix(init): address platform setup review

* fix(init): address cache setup review

* fix(init): hide workers cache option

* fix(init): align generated config indentation

* fix(init): validate cloudflare setup before mutation

* fix(init): preserve additive config syntax

* fix(init): tidy interactive prompt spacing

* fix(images): rename Cloudflare optimizer builder

* refactor(images): remove draft name migration

* fix(init): install dependencies after setup

* fix(init): clarify setup recovery steps

* fix(init): ignore Wrangler state for Cloudflare

* fix lockfile
2026-06-26 17:09:19 +01:00
James Anderson c5e16b1ad0 fix: sync trailing slash fixture lockfile (#2377) 2026-06-26 15:13:26 +00:00
James Anderson 42c3e24b40 fix(test): name trailing slash ISR fixture (#2376) 2026-06-26 13:58:53 +00:00
James Anderson da179857dc fix(app-router): render templates with children only (#2322)
* fix(app-router): render templates with children only

* test(app-router): correct server template navigation parity

* LGTM: template fix matches Next.js

Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>

* chore(test): remove fixture symlink noise

* LGTM: template fix matches Next.js

Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>

* fix(app-router): preserve template children-only fix

---------

Co-authored-by: ask-bonk[bot] <ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>
2026-06-26 14:51:46 +01:00
James Anderson 618cd66b30 fix(app-router): align static dynamic params parity (#2321)
* fix(app-router): align static dynamic params parity

* fix(app-router): preserve dynamic error fallback params

* chore(test): format force-static fixture
2026-06-26 14:45:37 +01:00
James Anderson 427609f5e0 fix(app-router): avoid probing client references (#2313) 2026-06-26 14:44:29 +01:00
James Anderson f05eeb8dde fix(cache): throw updateTag context errors synchronously (#2311) 2026-06-26 14:42:40 +01:00
James Anderson 126856cdc4 fix(config): match trailing-slash route sources (#2255)
* fix(routing): match slashed rewrite sources

* fix(routing): align redirect slash matching
2026-06-26 14:42:04 +01:00
dependabot[bot] de014d4e36 chore(deps): bump actions/cache from 5.0.5 to 6.0.0 (#2309)
Bumps [actions/cache](https://github.com/actions/cache) from 5.0.5 to 6.0.0.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...2c8a9bd7457de244a408f35966fab2fb45fda9c8)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-24 23:25:58 +01:00
James Anderson ffd28c133f fix(app-router): match dynamic request analysis parity (#2253)
* fix(app-router): ignore fully dynamic requests

* fix(app-router): match dynamic request analysis semantics

* fix(app-router): complete dynamic request analysis

* fix(app-router): complete dynamic request analysis

* fix(app-router): avoid unsafe dynamic request folding

* fix(build): respect static block request bindings

* fix(build): scope static block var bindings

* fix(build): scope dynamic request parameter defaults

* fix(build): honor dynamic request ignore comments

* fix(build): parse dynamic request comments safely

* perf(build): skip irrelevant dynamic request modules

* refactor(build): scope dynamic request analysis

* fix(build): track TypeScript value bindings

* fix(build): preserve bounded concat requests

* fix(build): harden dynamic request analysis

* fix(build): harden dynamic request analysis

* fix(build): preserve switch discriminant scope

* fix(build): resolve constant dynamic request expressions

* fix(build): align unary dynamic requests

* fix(build): preserve negative numeric dynamic requests

* fix(build): align remaining dynamic request analysis

* fix(build): align dynamic request sequence analysis

* fix(build): resolve constant string predicates

* fix(build): bound dynamic request alias resolution

* fix(build): resolve dynamic request aliases lexically

* fix(build): align dynamic request global constants

* fix(build): align NaN dynamic request predicates

* fix(build): include optimized transpile packages

* fix(build): align Turbopack package classification

* fix(build): align server transpile precedence
2026-06-24 19:24:10 +01:00
Alexander Lichter dba7d5cd50 feat(benchmarks): reduce repeated chart markers (#2286)
* feat(benchmarks): reduce repeated chart markers

* fix(benchmarks): group markers by displayed value
2026-06-24 10:13:18 +01:00
Alexander Lichter 6b3bc3adb8 feat(benchmarks): persist selected benchmark in URL (#2287)
* feat(benchmarks): persist selected benchmark in URL

* fix(benchmarks): hydrate benchmark URL selection

* fix(benchmarks): preserve browser query state

* fix(benchmarks): keep query parameter private
2026-06-24 10:11:13 +01:00
Jerry Zhao 6e5a30e21a docs(routing): document findFileWithExts' forward-slash contract (#2298) 2026-06-24 09:50:56 +01:00
Jerry Zhao ef748aa211 fix(pages-router): split scanned file paths on forward slashes (#2297) 2026-06-24 09:50:51 +01:00
Jerry Zhao c619aed43c docs(app-router): document buildAppRouteGraph's forward-slash appDir contract (#2300) 2026-06-24 09:50:39 +01:00
Jerry Zhao 843aa88b64 docs(app-router): document findFile's forward-slash contract (#2299) 2026-06-24 09:50:36 +01:00
Jerry Zhao ca599ed0dd docs(app-router): document directoryToAppRoute's forward-slash contract (#2301) 2026-06-24 09:50:31 +01:00
Jerry Zhao 9d601aef75 refactor(app-router): build fileToAppRoute paths with path.posix (#2302) 2026-06-24 09:50:18 +01:00
Jerry Zhao afa9f56223 refactor(app-router): compute discoverParallelSlots owner segments and key with path.posix.relative (#2303) 2026-06-24 09:50:11 +01:00
Jerry Zhao 49d0454b55 docs(app-router): document discoverInterceptingRoutes' forward-slash contract (#2304) 2026-06-24 09:50:00 +01:00
Jerry Zhao 04e4311ae0 refactor(app-router): descend scanForInterceptingPages with path.posix.join (#2305) 2026-06-24 09:49:32 +01:00
James Anderson ee551d1e28 fix(config): match deprecation warning parity (#2252)
* fix(config): match deprecation warning output

* fix(config): dedupe deprecation warnings

* fix(test): preserve lifecycle install diagnostics

* fix(check): report unsupported proxy config options
2026-06-23 20:39:39 +01:00
James Anderson b4843d75c1 feat(images): configure image optimization via vinext({ images }) adapter (#1873)
* feat(images): configure image optimization via vinext({ images }) adapter

Move server-side image optimization from a hand-wired custom worker entry to a
declarative `vinext({ images: { optimizer } })` option, mirroring the cache
adapter pattern. The default entries now handle `/_next/image` through a
registered optimizer, so no custom worker is required, and the same config
works across all targets — optimizing on Cloudflare, gracefully serving images
unoptimized on Node/dev where the binding is unavailable (like KV cache
degrading to in-memory).

- add an ImageOptimizer registry (set/getImageOptimizer +
  handleConfiguredImageOptimization) in server/image-optimization.ts
- generate `virtual:vinext-image-adapters` (registerConfiguredImageOptimizer)
  from the new `images` plugin option
- add @vinext/cloudflare/image/image-adapter: imageAdapter() builder + runtime
  factory reading the env.IMAGES binding
- handle /_next/image in the default app-router entry and the generated Pages
  worker via the registry; inline next.config `images` (allowed widths +
  security headers) into the RSC entry
- vinext deploy points App Router `main` at vinext/server/app-router-entry
  (no generated worker) and prints a hint to enable the optimizer

next.config `images` (remotePatterns, deviceSizes, dangerouslyAllowSVG, etc.)
continues to drive the standard Next.js options; the vite-config
`images.optimizer` only selects the runtime transform backend.

* fix(images): cover deploy image-hint helpers and preserve optimizer this-binding

The Check CI job failed because knip flagged viteConfigHasImageAdapter and
formatImageOptimizationHint as unused exports — they were only called inside
deploy.ts. Cover both with unit tests in tests/deploy.test.ts (mirroring the
existing viteConfigHasCacheAdapter / formatMissingCacheAdapterError suites),
which also closes the coverage gap for the new deploy hint path.

Also wrap the registered optimizer's transformImage in
handleConfiguredImageOptimization instead of detaching the method, so an
optimizer implemented as a class instance keeps its this binding.

* fix(images): honor configured deviceSizes/imageSizes on the App Router Node prod server

Review follow-up (ask-bonk):

- The App Router prod server (vinext start) validated /_next/image widths
  against the hardcoded Next.js defaults, rejecting valid optimizer URLs with
  400 when the app configures custom images.deviceSizes/imageSizes — while the
  Cloudflare worker entry and the Pages prod path already honored them. Read
  the __imageAllowedWidths constant inlined into the RSC entry (falling back to
  the defaults for older builds), matching how __assetPrefix/__basePath are read.
- Lock in the this-binding behavior of handleConfiguredImageOptimization with a
  class-instance optimizer test.

* fix(images): pass an explicit empty allowed-widths config through on vinext start

Review follow-up (ask-bonk, awareness note): the old-build fallback guard
conflated a missing __imageAllowedWidths export with an explicit empty
deviceSizes/imageSizes config, mapping the latter to the Next.js defaults on
the Node App Router path while the Cloudflare worker passes the empty array
straight through. Only fall back to the defaults when the export is absent.

* refactor(images): read App Router image config from the RSC entry, retire the JSON sidecar

Review follow-up (ask-bonk): the App Router had two parallel build-time sources
for next.config images security/header settings — the __imageConfig constant
inlined into the RSC entry (read by the Cloudflare worker entry) and the
image-config.json sidecar written by the vinext:image-config plugin (read by
vinext start). Unify on the RSC entry export: prod-server now reads
rscModule.__imageConfig, keeping image-config.json only as a read-side fallback
for dist outputs built by older vinext versions, and the sidecar writer plugin
is removed.

* fix(deploy): keep wrangler main on a user-authored worker entry for App Router

Review follow-up (ask-bonk): an App Router app with a custom worker/index.ts
but no wrangler.jsonc would have had its custom worker silently dropped —
generateWranglerConfig unconditionally pointed main at the default
vinext/server/app-router-entry. Respect hasWorkerEntry so a user-authored
worker keeps winning for both routers, with a regression test.

* fix(images): expose Cloudflare optimizer under images path

* fix(deploy): install Cloudflare image adapter package

* fix(examples): declare Cloudflare image adapter package

* test(images): update App Router image config codegen assertions

* fix(examples): configure image optimizer adapters
2026-06-23 20:20:36 +01:00
James Anderson 640e971ec5 fix(pages): match optional catch-all prerender paths (#2238)
* fix(pages): match empty optional catch-all static paths

* fix(pages): validate static path route params

* fix(pages): share static path matching in dev
2026-06-23 20:00:43 +01:00
James Anderson e00687a0f6 fix(middleware): match Pages data request metadata (#2239)
* fix(middleware): preserve Pages data routing metadata

* fix(middleware): preserve matched path on data misses

* test(pages): align middleware data miss assertions

* fix(pages): align dev middleware data misses

* fix(pages): gate data misses on real middleware

* fix(middleware): address data redirect review

* Reviewed PR #2239: fixes confirmed

Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>

* chore(tests): remove stray node_modules symlinks

---------

Co-authored-by: ask-bonk[bot] <ask-bonk[bot]@users.noreply.github.com>
Co-authored-by: james-elicx <james-elicx@users.noreply.github.com>
2026-06-23 19:39:59 +01:00