[PR #282] [MERGED] fix: strip server-only data-fetching exports from client bundles #441

Closed
opened 2026-05-06 12:39:50 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/282
Author: @southpolesteve
Created: 3/6/2026
Status: Merged
Merged: 3/6/2026
Merged by: @southpolesteve

Base: mainHead: fix/strip-server-exports-from-client


📝 Commits (2)

  • 3c1afa5 fix: strip getServerSideProps/getStaticProps from client bundles
  • 0e53c34 Rewrite stripServerExports to use AST instead of regex

📊 Changes

2 files changed (+409 additions, -0 deletions)

View changed files

📝 packages/vinext/src/index.ts (+127 -0)
📝 tests/build-optimization.test.ts (+282 -0)

📄 Description

Summary

  • Added a Vite transform plugin (vinext:strip-server-exports) that removes getServerSideProps, getStaticProps, and getStaticPaths exports from page modules in the client bundle
  • These functions often import server-only modules (database drivers, fs, etc.) that would break or bloat the client bundle. Next.js does this via an SWC transform; this adds the equivalent for vinext.
  • The transform replaces server exports with no-op stubs (export function getServerSideProps() { return { props: {} }; } or export const ... = undefined;) so the bundler can tree-shake their import chains
  • Only applies to client builds (not SSR) and only to files under the pages/ directory. API routes, _app, _document, and _error are excluded.
  • Handles multiple export patterns: export function, export async function, export const arrow functions, export const simple references, and TypeScript type annotations in parameters

Implementation

The core logic is in a standalone stripServerExports() function (exported as _stripServerExports for testing). It uses a skipBalanced() helper for bracket-aware scanning that correctly handles nested braces, string/template literals, line/block comments, and TypeScript type annotations.

Test plan

11 unit tests added to build-optimization.test.ts covering:

  • No-op when code has no server exports
  • export async function getServerSideProps stripping
  • export function getStaticProps stripping
  • export async function getStaticPaths + getStaticProps together
  • export const arrow function stripping
  • export const simple reference stripping
  • Preservation of non-server exports and default export
  • Nested braces in function bodies
  • Strings containing braces
  • TypeScript type annotations in function parameters

Full test suite (2142 tests) passes. Existing pages-router integration tests confirm no regressions.


🔄 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/282 **Author:** [@southpolesteve](https://github.com/southpolesteve) **Created:** 3/6/2026 **Status:** ✅ Merged **Merged:** 3/6/2026 **Merged by:** [@southpolesteve](https://github.com/southpolesteve) **Base:** `main` ← **Head:** `fix/strip-server-exports-from-client` --- ### 📝 Commits (2) - [`3c1afa5`](https://github.com/cloudflare/vinext/commit/3c1afa55781586fec54d8952442cd9f1af3c014e) fix: strip getServerSideProps/getStaticProps from client bundles - [`0e53c34`](https://github.com/cloudflare/vinext/commit/0e53c349434fd37b28a0b890f66923a5ee455e69) Rewrite stripServerExports to use AST instead of regex ### 📊 Changes **2 files changed** (+409 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/index.ts` (+127 -0) 📝 `tests/build-optimization.test.ts` (+282 -0) </details> ### 📄 Description ## Summary - Added a Vite transform plugin (`vinext:strip-server-exports`) that removes `getServerSideProps`, `getStaticProps`, and `getStaticPaths` exports from page modules in the client bundle - These functions often import server-only modules (database drivers, `fs`, etc.) that would break or bloat the client bundle. Next.js does this via an SWC transform; this adds the equivalent for vinext. - The transform replaces server exports with no-op stubs (`export function getServerSideProps() { return { props: {} }; }` or `export const ... = undefined;`) so the bundler can tree-shake their import chains - Only applies to client builds (not SSR) and only to files under the `pages/` directory. API routes, `_app`, `_document`, and `_error` are excluded. - Handles multiple export patterns: `export function`, `export async function`, `export const` arrow functions, `export const` simple references, and TypeScript type annotations in parameters ## Implementation The core logic is in a standalone `stripServerExports()` function (exported as `_stripServerExports` for testing). It uses a `skipBalanced()` helper for bracket-aware scanning that correctly handles nested braces, string/template literals, line/block comments, and TypeScript type annotations. ## Test plan 11 unit tests added to `build-optimization.test.ts` covering: - No-op when code has no server exports - `export async function getServerSideProps` stripping - `export function getStaticProps` stripping - `export async function getStaticPaths` + `getStaticProps` together - `export const` arrow function stripping - `export const` simple reference stripping - Preservation of non-server exports and default export - Nested braces in function bodies - Strings containing braces - TypeScript type annotations in function parameters Full test suite (2142 tests) passes. Existing pages-router integration tests confirm no regressions. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:39:50 +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#441
No description provided.