Skip to content

fix(vitest): resolve each inline project's own config under Vitest 5 - #370

Merged
ryansolid merged 2 commits into
nextfrom
fix/369-inline-runtime-client-tests
Sep 30, 2026
Merged

ryansolid merged 2 commits into
nextfrom
fix/369-inline-runtime-client-tests

Conversation

@brenelz

@brenelz brenelz commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Refs #369.

Under Vitest 5, inline projects in a test.projects workspace lost everything the plugin injects in test mode. A test.environment: 'node' project kept the root's browser condition, so isServer was false. A jsdom project lost the @testing-library/jest-dom setup file and failed with Invalid Chai property: toBeInTheDocument. It also lost the solid-js server.deps handling.

Root cause

Vitest 5 defaults test.sharedViteServer to true. An inline project that only changes test options reuses the root Vite server, and its options are resolved from the root test block that vitest:capture-raw-test-config captures before any plugin config hook runs. The plugin picks the client or server posture and adds its test.* values in that hook, so none of it reaches a shared project. Vitest 4.1.11 resolves a Vite config per project and is not affected.

The issue describes this as externalized dependencies missing the browser condition. I could not reproduce that exact symptom, but the workspace shape from the issue reproduces the shared-server failure above, and sharedViteServer: false alone fixes it.

Change

When the root config declares test.projects and leaves test.sharedViteServer unset, the config hook sets it to false, so every project resolves its own Vite config as it did under Vitest 4. An explicit user value is respected. Vitest reads the option from the resolved root config (getOwnServerReason), so setting it from a plugin hook is enough.

A narrower condition, such as disabling sharing only when project postures differ, would not work: a shared project with the same posture still loses the jest-dom setup file and the server.deps values. Conditions are Vite-level, so they cannot vary per project on one server either.

The README's vitest section documents the behavior, and a changeset is included.

Verification

Scratch project with two extends: true projects (jsdom and node), vitest@5.0.1, vite@8, solid-js/@solidjs/web 2.0.0-rc.9, @solidjs/testing-library@1.0.0-beta.3, and the plugin installed from pnpm pack. The tests assert isServer in each project, a testing-library render, and a jest-dom matcher.

  • Before, npx vitest run on 5.0.1: 2 failed, 2 passed. After: 4 passed.
  • 4 passed also with pool: 'threads' plus isolate: false, and with projects that omit extends.
  • Vitest 4.1.11: 4 passed before and after.
  • npx tsc --noEmit -p . is clean, and the examples/start-ssr VITEST_PROJECTS=1 suite passes (6 tests, Vitest 4.1.11).

Left open

No in-repo test runs on Vitest 5, because the examples pin vitest ^4.1.11. Covering this needs an example and lockfile bump.

🤖 Generated with Claude Code

Vitest 5 defaults test.sharedViteServer to true, so inline projects reuse
the root Vite server and never run the plugin's config hook. They lost the
per-project posture, the jest-dom setup file and the server.deps handling.
The plugin now sets sharedViteServer to false when the root config declares
test.projects and the user has not set the option.

Fixes #369
@changeset-bot

changeset-bot Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 59519fb

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

@pkg-pr-new

pkg-pr-new Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@solidjs/vite-plugin@370

commit: 59519fb

@ryansolid ryansolid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reproduced and verified — the code change is correct and I'd merge it, but the issue link needs changing.

What this fixes: under Vitest 5, inline test.projects share the root Vite server by default and take their test options from vitest:capture-raw-test-config, which snapshots the root test block before any plugin config hook runs. So a shared project never sees this plugin's posture, jest-dom setup file, or server.deps. getOwnServerReason reads sharedViteServer from the resolved root config, so returning false from the hook is honored. Confirmed with a two-project repro on vitest@5.0.2 (2 failed → 4 passed; explicit true respected; Vitest 4.1.11 unchanged). environment isn't in Vitest's VITE_AFFECTING_TEST_OPTIONS, so there's no narrower condition available — agreed with the PR's reasoning.

What it doesn't fix: #369 as reported. The reporter's follow-up says the symptom is Deno-only — Deno resolves the externalized testing-library's @solidjs/web import with deno/node conditions, both of which map to dist/server.js. On Node the testing-library render already passes on next. Please change "Fixes #369" → "Refs #369" (PR body, commit, changeset first sentence); we can decide separately whether #369 stays open as a Deno item.

Small asks:

  • Add a resolveConfig-level assertion in examples/start-ssr/test/run.mjs beside the projects-env check: sharedViteServer is false when projects is declared, undefined otherwise, preserved when explicit. Version-independent, so it covers this without a Vitest 5 example.
  • Expand the code comment at src/index.ts:1195 to name the raw-capture mechanism, so the condition isn't narrowed later.
  • README: mention that true also drops the server.deps handling, and that this trades Vitest 5's shared-server optimization for Vitest 4 behavior.
  • Changeset could be a couple of sentences rather than the full PR body.

No overlap with #371 — hunks are disjoint and a trial merge is clean.

— Claude via Cursor

…(Refs #369)

Co-authored-by: Cursor <cursoragent@cursor.com>
@ryansolid

Copy link
Copy Markdown
Member

Took this PR over to unblock the rc.13 release train — the review asks above are addressed in 59519fb, pushed on top of ec6c4dc (no rebase, no force-push).

  1. Fixes #369 → Refs #369 — PR body (first line) and the changeset. @solidjs/testing-library resolves @solidjs/web to the server build (isServer true) in jsdom tests under a multi-project vitest setup #369's reported symptom is Deno-only and stays open; this PR doesn't fully fix it. The original commit message keeps Fixes since rewriting it would mean a force-push.
  2. resolveConfig-level assertion — new shared-vite-server probe in examples/start-ssr/test/run.mjs (runVitestMode, right after projects-env). Three cases through resolveConfig: sharedViteServer === false when test.projects is declared and the user hasn't set it; undefined when no projects are declared (plugin leaves it alone); true preserved when set explicitly alongside projects. Confirmed it fails without the src/index.ts hunk (projects: undefined) and passes with it.
  3. Code comment on the src/index.ts hunk expanded to name the mechanism: Vitest 5's sharedViteServer default, the raw root test block captured before any config hook runs, and that getOwnServerReason reads the resolved root config — so the condition isn't narrowed later.
  4. README / changeset — the Vitest 5 paragraph now also says that sharedViteServer: true drops the plugin's server.deps handling for shared projects (both the server-posture inline and client-posture external live in the same config-hook block those projects bypass) and that the default trades Vitest 5's shared-server optimization for Vitest 4's per-project resolution. Changeset trimmed to three sentences ending in Refs #369.

Local examples/start-ssr vitest mode (node test/run.mjs vitest, Vitest 4.1.11): 6/6 assertions pass with the fix; 5/6 without it, the one failure being the new shared-vite-server probe. pnpm build (rollup + tsc) clean; hunks are prettier-neutral. Trial merges against next and chore/solid-rc13 are both clean. Note PR CI only runs the examples/vite-8 Cypress suite, so the local run is the evidence for this suite.

Thanks for the fix and the thorough root-cause writeup, @brenelz.

— Claude via Cursor

@ryansolid
ryansolid merged commit d6c40b1 into next Sep 30, 2026
6 checks passed
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