[PR #842] [MERGED] feat(build): wire build-time layout classification into RSC entry #893

Closed
opened 2026-05-06 13:10:42 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/842
Author: @NathanDrake2406
Created: 4/14/2026
Status: Merged
Merged: 4/20/2026
Merged by: @james-elicx

Base: mainHead: feat/pr-768-5-build-classification-wire


📝 Commits (10+)

  • ac081b1 feat(build): wire build-time layout classification into the generated RSC entry
  • 70e7a03 refactor(build): address Copilot review comments on PR 842
  • 83f4ddf refactor: address review comments on build classification PR
  • e91408d test: update entry-templates snapshots for module-load comment
  • 4707e2c refactor: address second round of review comments
  • 7ef82d0 refactor: address third round of review comments
  • 28b317f refactor: address subagent review findings
  • 6827a50 refactor: hoist build-time classification helpers and rename layer1 binding
  • c03ed6b Preserve module-graph reasons in classification manifest
  • 22a1731 Share module-graph static reason type

📊 Changes

12 files changed (+1427 additions, -70 deletions)

View changed files

packages/vinext/src/build/layout-classification-types.ts (+56 -0)
📝 packages/vinext/src/build/layout-classification.ts (+69 -10)
📝 packages/vinext/src/build/report.ts (+31 -15)
packages/vinext/src/build/route-classification-manifest.ts (+237 -0)
📝 packages/vinext/src/entries/app-rsc-entry.ts (+12 -1)
📝 packages/vinext/src/index.ts (+180 -0)
📝 tests/__snapshots__/entry-templates.test.ts.snap (+84 -0)
📝 tests/app-router.test.ts (+21 -0)
📝 tests/build-report.test.ts (+31 -14)
tests/build-time-classification-integration.test.ts (+249 -0)
📝 tests/layout-classification.test.ts (+62 -30)
tests/route-classification-manifest.test.ts (+395 -0)

📄 Description

Summary

Adds a build-time layout classification pipeline. A Rollup generateBundle hook patches the __VINEXT_CLASS stub in the generated RSC entry with a real dispatch table, built from segment-config (Layer 1) and module-graph (Layer 2) analysis. The runtime probe loop in app-page-execution.ts consults this table and skips the Layer 3 dynamic-isolation probe for layouts already proved static or dynamic at build time.

This lands as standalone reusable infrastructure. Build-time classification is the precondition for any future layout-skip optimization, independent of how the skip mechanism is implemented at runtime.

What changes

  • New build/route-classification-manifest.ts bridges the classifier with the entry template codegen.
  • New build/layout-classification-types.ts carries the tagged LayoutBuildClassification and ClassificationReason types. ClassificationReason is consumed by the debug sidecar follow-up; including it here keeps the codegen machinery self-contained.
  • classifyLayoutSegmentConfig in build/report.ts now returns LayoutBuildClassification instead of "static" | "dynamic" | null.
  • The runtime classification block in the generated RSC entry threads buildTimeClassifications through.
  • The generateBundle hook fails loudly if it sees __VINEXT_CLASS referenced without the recognized stub body, so the codegen template and the plugin cannot silently drift.

Context

This was originally PR 5 of a 6-PR stack (#838, #839, #840, #841, this PR, #843). #838 and #839 landed. #840 and #841 are closed: their server-side skip mechanism relied on rewriting the React Flight wire-format payload on egress, which proved too coupled to React-internal tag conventions for a framework that does not vendor React. The skip-mechanism design is being reworked separately around render-time omission rather than byte-level filtering.

This PR is unaffected by that decision. The classifier is needed for any approach. The runtime probe loop already short-circuits on its output, so this PR is useful even before the new skip mechanism lands.

#843 still depends on this PR for the ClassificationReason machinery.

Test plan

  • tests/route-classification-manifest.test.ts (44 tests)
  • tests/build-time-classification-integration.test.ts (5 tests)
  • tests/build-report.test.ts
  • tests/layout-classification.test.ts
  • tests/app-router.test.ts (build-time classification dispatch stub cases)
  • tests/entry-templates.test.ts (snapshot regenerated)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/842 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 4/14/2026 **Status:** ✅ Merged **Merged:** 4/20/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `feat/pr-768-5-build-classification-wire` --- ### 📝 Commits (10+) - [`ac081b1`](https://github.com/cloudflare/vinext/commit/ac081b18426c62d183483d5c9f23dcd8dfd1a143) feat(build): wire build-time layout classification into the generated RSC entry - [`70e7a03`](https://github.com/cloudflare/vinext/commit/70e7a038e374fc95c45471fdd215bbcef879ac67) refactor(build): address Copilot review comments on PR 842 - [`83f4ddf`](https://github.com/cloudflare/vinext/commit/83f4ddf2936fb156673072e9a1340f8cebee9af9) refactor: address review comments on build classification PR - [`e91408d`](https://github.com/cloudflare/vinext/commit/e91408daa410fefc787929ac9d0f8b237b6b0a6a) test: update entry-templates snapshots for module-load comment - [`4707e2c`](https://github.com/cloudflare/vinext/commit/4707e2cb5bc1a956675299e1d8534c5a28ca32a9) refactor: address second round of review comments - [`7ef82d0`](https://github.com/cloudflare/vinext/commit/7ef82d09d1d87de1eb805bb116529a6dc73daa5f) refactor: address third round of review comments - [`28b317f`](https://github.com/cloudflare/vinext/commit/28b317f110d7877da96bfa1bdf20826b36747baf) refactor: address subagent review findings - [`6827a50`](https://github.com/cloudflare/vinext/commit/6827a502f1743ad89672186160488bd7f267a440) refactor: hoist build-time classification helpers and rename layer1 binding - [`c03ed6b`](https://github.com/cloudflare/vinext/commit/c03ed6bd5d8a60a6356baef3cef231013b649132) Preserve module-graph reasons in classification manifest - [`22a1731`](https://github.com/cloudflare/vinext/commit/22a173136e78f1847d968c5ba62e4320bd95b720) Share module-graph static reason type ### 📊 Changes **12 files changed** (+1427 additions, -70 deletions) <details> <summary>View changed files</summary> ➕ `packages/vinext/src/build/layout-classification-types.ts` (+56 -0) 📝 `packages/vinext/src/build/layout-classification.ts` (+69 -10) 📝 `packages/vinext/src/build/report.ts` (+31 -15) ➕ `packages/vinext/src/build/route-classification-manifest.ts` (+237 -0) 📝 `packages/vinext/src/entries/app-rsc-entry.ts` (+12 -1) 📝 `packages/vinext/src/index.ts` (+180 -0) 📝 `tests/__snapshots__/entry-templates.test.ts.snap` (+84 -0) 📝 `tests/app-router.test.ts` (+21 -0) 📝 `tests/build-report.test.ts` (+31 -14) ➕ `tests/build-time-classification-integration.test.ts` (+249 -0) 📝 `tests/layout-classification.test.ts` (+62 -30) ➕ `tests/route-classification-manifest.test.ts` (+395 -0) </details> ### 📄 Description ## Summary Adds a build-time layout classification pipeline. A Rollup `generateBundle` hook patches the `__VINEXT_CLASS` stub in the generated RSC entry with a real dispatch table, built from segment-config (Layer 1) and module-graph (Layer 2) analysis. The runtime probe loop in `app-page-execution.ts` consults this table and skips the Layer 3 dynamic-isolation probe for layouts already proved static or dynamic at build time. This lands as standalone reusable infrastructure. Build-time classification is the precondition for any future layout-skip optimization, independent of how the skip mechanism is implemented at runtime. ## What changes - New `build/route-classification-manifest.ts` bridges the classifier with the entry template codegen. - New `build/layout-classification-types.ts` carries the tagged `LayoutBuildClassification` and `ClassificationReason` types. `ClassificationReason` is consumed by the debug sidecar follow-up; including it here keeps the codegen machinery self-contained. - `classifyLayoutSegmentConfig` in `build/report.ts` now returns `LayoutBuildClassification` instead of `"static" | "dynamic" | null`. - The runtime `classification` block in the generated RSC entry threads `buildTimeClassifications` through. - The `generateBundle` hook fails loudly if it sees `__VINEXT_CLASS` referenced without the recognized stub body, so the codegen template and the plugin cannot silently drift. ## Context This was originally PR 5 of a 6-PR stack (#838, #839, #840, #841, this PR, #843). #838 and #839 landed. #840 and #841 are closed: their server-side skip mechanism relied on rewriting the React Flight wire-format payload on egress, which proved too coupled to React-internal tag conventions for a framework that does not vendor React. The skip-mechanism design is being reworked separately around render-time omission rather than byte-level filtering. This PR is unaffected by that decision. The classifier is needed for any approach. The runtime probe loop already short-circuits on its output, so this PR is useful even before the new skip mechanism lands. #843 still depends on this PR for the `ClassificationReason` machinery. ## Test plan - [x] `tests/route-classification-manifest.test.ts` (44 tests) - [x] `tests/build-time-classification-integration.test.ts` (5 tests) - [x] `tests/build-report.test.ts` - [x] `tests/layout-classification.test.ts` - [x] `tests/app-router.test.ts` (build-time classification dispatch stub cases) - [x] `tests/entry-templates.test.ts` (snapshot regenerated) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:10:42 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#893
No description provided.