Skip to content

test: reproduce getPrerenderPaths limitation with virtual modules - #13

Closed
hyfdev wants to merge 3 commits into
mainfrom
test/prerender-virtual-module-limitation
Closed

hyfdev wants to merge 3 commits into
mainfrom
test/prerender-virtual-module-limitation

Conversation

@hyfdev

@hyfdev hyfdev commented Mar 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The fundamental problem

The configFile: false fix avoids the FetchableDevEnvironment crash by not loading the user's config at all. But this means the ssrLoadModule runtime used by collectPrerenderPaths is inconsistent with the user's actual Vite environment — no user plugins, no resolve.alias, no custom resolve config.

The most severe case is plugins providing virtual modules (reproduced here) — any getPrerenderPaths that imports from a virtual module will silently fail. Smaller cases include custom resolve.alias (e.g. { "@": "./src" }) and other resolve config that users may rely on in their server files.

Why CI fails

The test failure is intentional — it's caused by the assertion we added in this PR, not by a regression. Before #14, collectPrerenderPaths silently swallowed the error as a console.warn and the build succeeded (just with missing pages). After #14 lands, the build itself will fail with a hard error instead.

Related

🤖 Generated with Claude Code

The configFile: false fix (#12) prevents user plugins from loading
during collectPrerenderPaths, so getPrerenderPaths that imports a
virtual module silently fails to resolve prerender paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 2, 2026 16:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a tags/[tag] dynamic page to the static-pages playground to demonstrate a known framework limitation: because collectPrerenderPaths uses createServer({ configFile: false }) (the fix from issue #12), user plugins (such as virtual module plugins or resolve.alias entries) are not loaded when getPrerenderPaths runs. The result is that tags/vue.html and tags/vite.html are never generated, with a silent warning about Cannot find module 'virtual:tags'.

Changes:

  • Introduces a virtualTagsPlugin() in vite.config.ts that serves a virtual:tags module exporting ["vue", "vite"]
  • Adds pages/tags/[tag].vue — the Vue component for the tag page
  • Adds pages/tags/[tag].server.ts — imports virtual:tags in getPrerenderPaths to trigger the limitation

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
playground/static-pages/vite.config.ts Adds a virtualTagsPlugin Vite plugin providing the virtual:tags virtual module
playground/static-pages/pages/tags/[tag].vue New Vue component rendering a tag page with a data-testid attribute
playground/static-pages/pages/tags/[tag].server.ts New server file importing virtual:tags in getPrerenderPaths, reproducing the silent failure

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +10 to +11
export function getPrerenderPaths() {
return tags.map((tag: string) => ({ tag }));

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

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

The PR's stated purpose is to reproduce a known limitation — virtual module imports (and resolve.alias) silently fail during getPrerenderPaths because collectPrerenderPaths uses createServer({ configFile: false }). However, the existing static-pages.test.ts integration test is not updated to document or assert on this behavior.

Without a corresponding test case asserting that tags/vue.html and tags/vite.html are not generated (e.g., expect(existsSync(join(DIST, "client/tags/vue.html"))).toBe(false)), there is no automated check capturing the limitation. This means the limitation could be silently "fixed" or "broken" without any test reflecting the change.

Consider adding a test case to packages/void/test/integration/static-pages.test.ts that explicitly documents this known limitation — for example, asserting that the tag pages are absent from the build output due to the virtual module resolution failure. Such a test would also serve as a regression test once the limitation is eventually fixed (the test expectation would be inverted).

Copilot uses AI. Check for mistakes.
hyfdev and others added 2 commits March 3, 2026 09:31
This will fail until collectPrerenderPaths loads user plugins.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
If a user explicitly exports getPrerenderPaths and it fails to resolve,
the build should fail with a clear error instead of silently skipping
the page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
hyfdev added a commit that referenced this pull request Mar 3, 2026
…pport

`collectPrerenderPaths()` creates a temporary Vite dev server to call
`ssrLoadModule()` on page files that export `getPrerenderPaths`. Previously
it used `configFile: false`, which meant no user plugins were loaded —
any `getPrerenderPaths` that imported from a virtual module or relied on
resolve aliases would silently fail.

Now uses `loadConfigFromFile()` to fully load the user's Vite config,
then filters out only the two problematic plugin sets:

- `void:*` plugins — would cause recursion (prerenderPlugin → collectPrerenderPaths → createServer → voidPlugin → prerenderPlugin...)
- `vite-plugin-cloudflare*` — replaces SSR environment with FetchableDevEnvironment that requires a running Miniflare backend, making ssrLoadModule() unusable

All other user plugins (virtual modules, resolve aliases, etc.) are
forwarded to the temporary server, ensuring consistent module resolution.

Fixes #12, supersedes #13.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@hyfdev

hyfdev commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #16 — virtual module tests and error handling consolidated there.

@hyfdev hyfdev closed this Mar 3, 2026
TheAlexLichter added a commit that referenced this pull request May 4, 2026
…transform

Vite's SSR dep optimizer prebundled @void/solid with esbuild's default
automatic JSX transform, emitting imports of react/jsx-runtime that
failed to resolve. Set optimizeDeps.exclude, ssr.noExternal, and
ssr.optimizeDeps.exclude from voidSolid() so vite-plugin-solid sees
the .tsx source directly.

Closes #13
@cpojer
cpojer deleted the test/prerender-virtual-module-limitation branch May 7, 2026 07:54
cpojer pushed a commit that referenced this pull request Sep 11, 2026
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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.

2 participants