[PR #146] [CLOSED] fix: resolve vinext imports under pnpm strict hoisting #349

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

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/146
Author: @jpoindexter
Created: 2/26/2026
Status: Closed

Base: mainHead: fix/pnpm-strict-hoisting


📝 Commits (2)

  • fbe7652 fix: resolve vinext imports under pnpm strict hoisting
  • bb72949 fix: use createBuilder().buildApp() for Pages Router deploy

📊 Changes

2 files changed (+30 additions, -29 deletions)

View changed files

📝 packages/vinext/src/deploy.ts (+5 -14)
📝 packages/vinext/src/index.ts (+25 -15)

📄 Description

Summary

Fixes three issues that break vinext under pnpm strict hoisting (the default mode), affecting both standalone pnpm projects and pnpm workspaces.

All three issues are invisible under npm/yarn flat hoisting but cause hard failures with pnpm.

1. @vitejs/plugin-rsc resolution fallback

Problem: @vitejs/plugin-rsc is a dependency of vinext, but under pnpm strict hoisting it is NOT symlinked to the consumer's node_modules/. The createRequire() call at line ~1591 resolves from the consumer project root, which fails because the consumer never declared @vitejs/plugin-rsc as a dependency.

Fix: Add a fallback try/catch that resolves from vinext's own location via createRequire(import.meta.url).

2. vinext/shims/* resolveId for Rollup SSR builds

Problem: The resolveId hook filter regex (/(?:next\/|virtual:vinext-)/) does not match vinext/ imports. During Rollup SSR production builds, imports like vinext/shims/document fail to resolve because Rollup's bundler doesn't reliably follow the "./shims/*" package exports glob through pnpm symlinks.

Fix: Extend the resolveId filter to include vinext\/ and add a handler that resolves vinext/shims/* to the shims directory (with path traversal guard).

3. Pages Router deploy fails: Could not resolve entry module "index.html"

Problem: vinext deploy calls Vite's build() JS API for Pages Router projects. build() forces the legacy single-environment builder path which ignores per-environment configs set by the cloudflare() plugin and falls back to looking for index.html — which doesn't exist in Pages Router mode.

App Router worked because it already used createBuilder().buildApp().

Fix: Use createBuilder().buildApp() for both routers. The cloudflare() plugin sets a custom buildApp that orchestrates multi-environment builds (worker + client), which is required for both router types.

Test plan

  • pnpm build — vinext package builds cleanly
  • pnpm test — 50 files, 2,011 tests pass, 3 skipped (no regressions)
  • Verified all three fixes against a real pnpm workspace consumer project (fabrk-framework)

Reproduction

# Fix 1: App Router + pnpm → @vitejs/plugin-rsc fails
pnpm add vinext && mkdir app
# Error: App Router detected but @vitejs/plugin-rsc is not installed.

# Fix 2: Pages Router + pnpm → vinext/shims/* fails in SSR build
mkdir pages && echo 'import { Html } from "vinext/shims/document"' > pages/_document.tsx
pnpm vinext build
# Error: Rollup failed to resolve import "vinext/shims/document"

# Fix 3: Pages Router + vinext deploy → index.html not found
pnpm vinext deploy --dry-run  # generates config
pnpm vinext deploy
# Error: Could not resolve entry module "index.html"

Built with FABRK Framework — discovered while building the first AI-first React framework on top of vinext.


🔄 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/146 **Author:** [@jpoindexter](https://github.com/jpoindexter) **Created:** 2/26/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/pnpm-strict-hoisting` --- ### 📝 Commits (2) - [`fbe7652`](https://github.com/cloudflare/vinext/commit/fbe7652f7f8ce17af9ec7876f03e8dbc49137d7e) fix: resolve vinext imports under pnpm strict hoisting - [`bb72949`](https://github.com/cloudflare/vinext/commit/bb72949e014209d1af1d40472d9ebd2f6bb8f0c4) fix: use createBuilder().buildApp() for Pages Router deploy ### 📊 Changes **2 files changed** (+30 additions, -29 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/deploy.ts` (+5 -14) 📝 `packages/vinext/src/index.ts` (+25 -15) </details> ### 📄 Description ## Summary Fixes three issues that break vinext under **pnpm strict hoisting** (the default mode), affecting both standalone pnpm projects and pnpm workspaces. All three issues are invisible under npm/yarn flat hoisting but cause hard failures with pnpm. ### 1. `@vitejs/plugin-rsc` resolution fallback **Problem:** `@vitejs/plugin-rsc` is a dependency of vinext, but under pnpm strict hoisting it is NOT symlinked to the consumer's `node_modules/`. The `createRequire()` call at line ~1591 resolves from the consumer project root, which fails because the consumer never declared `@vitejs/plugin-rsc` as a dependency. **Fix:** Add a fallback `try/catch` that resolves from vinext's own location via `createRequire(import.meta.url)`. ### 2. `vinext/shims/*` resolveId for Rollup SSR builds **Problem:** The `resolveId` hook filter regex (`/(?:next\/|virtual:vinext-)/`) does not match `vinext/` imports. During Rollup SSR production builds, imports like `vinext/shims/document` fail to resolve because Rollup's bundler doesn't reliably follow the `"./shims/*"` package exports glob through pnpm symlinks. **Fix:** Extend the `resolveId` filter to include `vinext\/` and add a handler that resolves `vinext/shims/*` to the shims directory (with path traversal guard). ### 3. Pages Router deploy fails: `Could not resolve entry module "index.html"` **Problem:** `vinext deploy` calls Vite's `build()` JS API for Pages Router projects. `build()` forces the legacy single-environment builder path which ignores per-environment configs set by the `cloudflare()` plugin and falls back to looking for `index.html` — which doesn't exist in Pages Router mode. App Router worked because it already used `createBuilder().buildApp()`. **Fix:** Use `createBuilder().buildApp()` for both routers. The `cloudflare()` plugin sets a custom `buildApp` that orchestrates multi-environment builds (worker + client), which is required for both router types. ## Test plan - [x] `pnpm build` — vinext package builds cleanly - [x] `pnpm test` — 50 files, 2,011 tests pass, 3 skipped (no regressions) - [x] Verified all three fixes against a real pnpm workspace consumer project (fabrk-framework) ## Reproduction ```bash # Fix 1: App Router + pnpm → @vitejs/plugin-rsc fails pnpm add vinext && mkdir app # Error: App Router detected but @vitejs/plugin-rsc is not installed. # Fix 2: Pages Router + pnpm → vinext/shims/* fails in SSR build mkdir pages && echo 'import { Html } from "vinext/shims/document"' > pages/_document.tsx pnpm vinext build # Error: Rollup failed to resolve import "vinext/shims/document" # Fix 3: Pages Router + vinext deploy → index.html not found pnpm vinext deploy --dry-run # generates config pnpm vinext deploy # Error: Could not resolve entry module "index.html" ``` --- Built with [FABRK Framework](https://github.com/jpoindexter/fabrk-framework) — discovered while building the first AI-first React framework on top of vinext. --- <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:21 +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#349
No description provided.