Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/vitest-5-shared-server-projects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vite-plugin-solid': patch
---

When the root config declares `test.projects` and leaves `test.sharedViteServer` unset, the plugin now sets it to `false` so every inline project resolves its own Vite config, as under Vitest 4. An explicit value is respected. Vitest 5 defaults the option to `true`, and a shared inline project takes its `test` options from the raw root block captured before any `config` hook runs, so it lost everything the plugin injects (the `jsdom` default, the `@testing-library/jest-dom` setup file, `server.deps`). Ports solidjs/solid-vite-plugin#370; refs #369.
5 changes: 5 additions & 0 deletions .changeset/vitest-client-inline-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'vite-plugin-solid': patch
---

In Vitest DOM tests (the jsdom default, no `ssr` option), the plugin now inlines `solid-js` and the packages that import it without a `solid` export condition, such as `@solidjs/testing-library`. Before, they stayed external, and the host runtime resolved their own imports. Node gets the `browser` condition from Vitest's worker `--conditions`, but Deno does not apply it in worker threads and resolves `deno`/`node`. Under Deno, `@solidjs/testing-library` loaded the server build of `solid-js/web` and `render` threw "Client-only API called on the server side" (solidjs/solid-vite-plugin#369). Inlining sends these imports through Vite's `browser` condition and loads one client-build instance. A `test.server.deps.inline` list is merged with the plugin's, and a `test.server.deps.external` entry for `solid-js` still opts out. With `ssr: true`, tests keep `solid-js` external as before.
4 changes: 4 additions & 0 deletions .github/workflows/vitest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ jobs:
- name: Run tests
working-directory: examples/vite-6
run: pnpm run test

- name: Run jsdom tests
working-directory: examples/vite-6
run: pnpm run test:jsdom
4 changes: 3 additions & 1 deletion examples/vite-6/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
"build": "vite build",
"preview": "vite preview",
"test": "vitest --browser.headless --run",
"test-dev": "vitest"
"test-dev": "vitest",
"test:jsdom": "NODE_OPTIONS=--import=./tests/deno-conditions.mjs vitest --run --config vitest.jsdom.config.ts --pool=forks"
},
"devDependencies": {
"@solidjs/testing-library": "^0.8.10",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/user-event": "^14.6.1",
"@vitest/browser": "^3.0.7",
"jsdom": "^26.0.0",
"playwright": "^1.50.1",
"vite": "^6.2.0",
"vite-plugin-solid": "workspace:*",
Expand Down
29 changes: 29 additions & 0 deletions examples/vite-6/tests/deno-conditions.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Preloaded into the vitest workers (NODE_OPTIONS=--import) by `test:jsdom`.
// It makes Node resolve bare imports the way Deno does in a worker thread.
// Deno does not apply the `browser` condition that vitest passes to the
// workers as `--conditions`, so an externalized package's own
// `import "solid-js/web"` resolves `deno`/`node`, which is the server build
// (solidjs/solid-vite-plugin#369).
import module from 'node:module';

const denoConditions = (context) => ({
...context,
conditions: [...context.conditions.filter((c) => c !== 'browser'), 'deno'],
});

if (module.registerHooks) {
module.registerHooks({
resolve: (specifier, context, next) => next(specifier, denoConditions(context)),
});
} else {
// Node < 22.15 has only the async loader API.
module.register(
'data:text/javascript,' +
encodeURIComponent(`
export async function resolve(specifier, context, next) {
const conditions = context.conditions.filter((c) => c !== 'browser');
return next(specifier, { ...context, conditions: [...conditions, 'deno'] });
}
`),
);
}
33 changes: 33 additions & 0 deletions examples/vite-6/tests/jsdom/testing-library.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// jsdom regression test for solidjs/solid-vite-plugin#369, run by
// `pnpm test:jsdom` with tests/deno-conditions.mjs preloaded.
// `@solidjs/testing-library` has no `solid` export condition. Left external,
// its own `import "solid-js/web"` is resolved by the host runtime, and under
// Deno that is the server build, so `render` threw "Client-only API called
// on the server side". The plugin inlines it with solid-js, so its imports
// go through Vite's `browser` condition and share the test file's instance.
import { render } from '@solidjs/testing-library';
import { createSignal } from 'solid-js';
import { isServer } from 'solid-js/web';
import { expect, test } from 'vitest';

function Counter() {
const [count, setCount] = createSignal(0);
return (
<button type="button" onClick={() => setCount(count() + 1)}>
count: {count()}
</button>
);
}

test('resolves the browser build in the test file', () => {
expect(isServer).toBe(false);
});

test('renders and updates through @solidjs/testing-library', () => {
const { getByRole, unmount } = render(() => <Counter />);
const button = getByRole('button');
expect(button.textContent).toBe('count: 0');
button.click();
expect(button.textContent).toBe('count: 1');
unmount();
});
4 changes: 3 additions & 1 deletion examples/vite-6/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineConfig } from 'vitest/config';
import { configDefaults, defineConfig } from 'vitest/config';
import solidPlugin from '../../src/index.js';

export default defineConfig({
Expand All @@ -8,6 +8,8 @@ export default defineConfig({
},
test: {
environment: 'node',
// tests/jsdom runs under vitest.jsdom.config.ts (`pnpm test:jsdom`).
exclude: [...configDefaults.exclude, 'tests/jsdom/**'],
browser: {
enabled: true,
provider: 'playwright',
Expand Down
12 changes: 12 additions & 0 deletions examples/vite-6/vitest.jsdom.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'vitest/config';
import solidPlugin from '../../src/index.js';

// jsdom suite (`pnpm test:jsdom`). The default vitest.config.ts runs the
// browser-mode suite and excludes tests/jsdom.
export default defineConfig({
plugins: [solidPlugin()],
test: {
environment: 'jsdom',
include: ['tests/jsdom/**/*.test.tsx'],
},
});
58 changes: 16 additions & 42 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading