Skip to content

fix: pre-bundle the server-function client runtime - #395

Open
everton-dgn wants to merge 1 commit into
solidjs:nextfrom
everton-dgn:fix/server-functions-optimize-deps
Open

everton-dgn wants to merge 1 commit into
solidjs:nextfrom
everton-dgn:fix/server-functions-optimize-deps

Conversation

@everton-dgn

Copy link
Copy Markdown

With serverFunctions: true and no components, a Vitest browser test that imports a 'use server' module logs this on a cold cache:

[vite] (client) dependency optimized: @solidjs/web/server-functions
[vite] (client) optimized dependencies changed. reloading

[vitest] Vite unexpectedly reloaded a test. This may cause tests to fail, lead to flaky behaviour or duplicated test runs.
For a stable experience, add the newly optimized dependencies to your config's `optimizeDeps.include` field manually.

The test still passed in all my runs, so the cost is one reload plus that warning on each cold start.

The server-function compiler adds the createServerReference import from runtime.client during transform (server-functions/index.ts#L381, #L427-L438). The dep scanner doesn't run that transform (the only plugin this package adds to the scan is solid:tsrx-dep-scan, for .tsrx files, index.ts#L1503-L1525), and the runtime is only in optimizeDeps.include when serverComponents is on (index.ts#L1476-L1485).

Under serve, this adds the client runtime whenever serverFunctions is on: @solidjs/web/server-functions by default, or runtime.client when it is a package specifier. It sits in the same place and form as the solid-js/attribution and @solidjs/web/performance-tracks entries from #374. The serverComponents branch is unchanged, and the default runtime is listed once when both apply. The standalone serverFunctions() export still doesn't add the entry.

Paths, aliases and virtual ids stay out on purpose. I checked what Vite 8.2.1 does with each one in include on a small dev server: a relative path or a ~/x alias builds a copy the browser never loads, an @/x alias gets served from the deps cache in place of the source (edits stopped showing up, even after a restart), and a virtual id or a root-relative /src/x doesn't resolve, so it only logs "Failed to resolve dependency" on a cold cache. The check is syntactic, so an alias that looks like a package name would still be added.

Testing:

  • examples/start-ssr/test/components-warning.mjs gets the new assertions. The file passes 19 of its 23 checks on next (e4cdee4), failing the four positive cases, and 23/23 with this change. Dropping the duplicate guard fails only the "listed once" case.
  • That file runs in the start-ssr step of release.yml, on pushes to main and next. The PR workflows only test examples/vite-8 (vitest.yml, and e2e.yml through the root pnpm test), which doesn't exercise this: its Vitest config has no serverFunctions, and the e2e job is build plus preview. Both pass with this change.
  • pnpm build, tsc --noEmit -p tsconfig.json and the five suites release.yml runs (start-ssr, start-client, ssr, css-matrix, start-env) pass.
  • Vitest 5.0.1 browser mode (Playwright, Chromium, run through Vite+) in an app with solid({ serverFunctions: true }), no optimizeDeps.include in the user config, cold cache before each run, variants interleaved: the reload and warning showed up in 3/3 runs with 3.0.0-next.47 and 0/3 with its dist/ swapped for this branch's build. All six runs passed. Adding optimizeDeps: { include: ['@solidjs/web/server-functions'] } to the user config instead gave the same 0/3 in an earlier set of runs.

Compiled server-function references import the client runtime
(`@solidjs/web/server-functions` by default), but the dependency scanner
never runs the server-function transform that adds that import. Only
`serverFunctions.components` put the runtime in `optimizeDeps.include`, so
with plain `serverFunctions` the first "use server" module discovered it
late and forced a re-optimize and full reload (in Vitest browser mode:
"Vite unexpectedly reloaded a test").

Under `serve`, include the client runtime whenever `serverFunctions` is on:
the default, or `runtime.client` when it is a package specifier. A path or
an alias is app source, and a virtual id doesn't resolve for `include`, so
those stay out. The server-components branch is unchanged and the default
runtime is listed once.

Tests (examples/start-ssr/test/components-warning.mjs): included with
`serverFunctions: true` with and without `ssr`, with a custom package
runtime, and beside the components entries when both are on; not included
without `serverFunctions`, in build, or for path, virtual or alias
runtimes; listed once with components on.
@changeset-bot

changeset-bot Bot commented Oct 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2a714d4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@solidjs/vite-plugin Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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.

1 participant