Skip to content

Commit 429bd62

Browse files
Skip dev server setup in configureServer when running inside Vitest (#17248)
* fix(server): skip dev server plugin setup in Vitest to prevent wrapDynamicImport crash (#16275) * Apply suggestion from @matthewp --------- Co-authored-by: Matthew Phillips <matthewphillips@cloudflare.com>
1 parent ed6bea5 commit 429bd62

3 files changed

Lines changed: 59 additions & 0 deletions

File tree

.changeset/sweet-trains-follow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fixes a crash when using Astro's `getViteConfig` with Vitest browser mode (e.g., Storybook vitest runner). Astro now skips dev server setup inside Vitest, preventing errors.

packages/astro/src/vite-plugin-astro-server/plugin.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ export default function createVitePluginAstroServer({
3535
return environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr;
3636
},
3737
async configureServer(viteServer) {
38+
// Skip Astro dev server setup when running inside Vitest. The dev server
39+
// middleware (SSR handler, prerender handler, trailing-slash redirects, etc.)
40+
// is only needed for `astro dev` and can crash in Vitest's browser server
41+
// where the module evaluator may not support dynamic imports.
42+
if (process.env.VITEST) {
43+
return;
44+
}
45+
3846
const ssrEnvironment = viteServer.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr];
3947
const prerenderEnvironment = viteServer.environments[ASTRO_VITE_ENVIRONMENT_NAMES.prerender];
4048

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import assert from 'node:assert/strict';
2+
import { afterEach, describe, it } from 'node:test';
3+
import createVitePluginAstroServer from '../../../dist/vite-plugin-astro-server/plugin.js';
4+
import { createBasicSettings } from '../test-utils.ts';
5+
import { defaultLogger } from '../test-utils.ts';
6+
7+
describe('astro:server configureServer vitest guard', () => {
8+
const originalVitest = process.env.VITEST;
9+
10+
afterEach(() => {
11+
if (originalVitest !== undefined) {
12+
process.env.VITEST = originalVitest;
13+
} else {
14+
delete process.env.VITEST;
15+
}
16+
});
17+
18+
it('skips server setup when process.env.VITEST is set', async () => {
19+
process.env.VITEST = 'true';
20+
const settings = await createBasicSettings({});
21+
const plugin = createVitePluginAstroServer({ settings, logger: defaultLogger });
22+
23+
// configureServer should return early without throwing when VITEST is set,
24+
// even with a fake viteServer that has no environments
25+
const fakeViteServer = {} as any;
26+
const result = await (plugin as any).configureServer(fakeViteServer);
27+
28+
// Early return produces undefined (no middleware callback)
29+
assert.equal(result, undefined);
30+
});
31+
32+
it('attempts server setup when process.env.VITEST is not set', async () => {
33+
delete process.env.VITEST;
34+
const settings = await createBasicSettings({});
35+
const plugin = createVitePluginAstroServer({ settings, logger: defaultLogger });
36+
37+
// Without VITEST, configureServer should try to access viteServer.environments
38+
// and fail because our fake server has none
39+
const fakeViteServer = { environments: {} } as any;
40+
// Should not throw — it will just have no runnable environments
41+
const result = await (plugin as any).configureServer(fakeViteServer);
42+
43+
// When there are no runnable environments, it returns a middleware setup function
44+
assert.equal(typeof result, 'function');
45+
});
46+
});

0 commit comments

Comments
 (0)