From fe5a5ff75a2d3d6193fc8e59fe66f7bbd77f85e5 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Fri, 8 Sep 2023 11:10:05 +0300 Subject: [PATCH 1/4] fix(vitest): don't start the server when optimizer is enabled --- packages/vitest/src/node/config.ts | 9 ++++++++- packages/vitest/src/node/create.ts | 5 +---- packages/vitest/src/node/plugins/index.ts | 2 +- packages/vitest/src/node/plugins/workspace.ts | 1 + packages/vitest/src/node/workspace.ts | 5 +---- packages/vitest/src/types/config.ts | 4 ++-- test/core/package.json | 1 + test/core/{vitest.config.ts => vite.config.ts} | 3 +++ 8 files changed, 18 insertions(+), 12 deletions(-) rename test/core/{vitest.config.ts => vite.config.ts} (98%) diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 00f64eaecd3c..4682d7af632c 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -27,7 +27,11 @@ export function resolveApiServerConfig( ): ApiConfig | undefined { let api: ApiConfig | undefined - if (options.ui && !options.api) + const optimizer = options.deps?.optimizer + const optimizerEnabled = optimizer?.web?.enabled !== false || optimizer?.ssr?.enabled !== false + const needApi = options.ui || optimizerEnabled + + if (needApi && !options.api) api = { port: defaultPort } else if (options.api === true) api = { port: defaultPort } @@ -52,6 +56,9 @@ export function resolveApiServerConfig( if (!api.port) api.port = defaultPort } + else { + api = { middlewareMode: true } + } return api } diff --git a/packages/vitest/src/node/create.ts b/packages/vitest/src/node/create.ts index a0b9dec101e8..e9d72c0edc62 100644 --- a/packages/vitest/src/node/create.ts +++ b/packages/vitest/src/node/create.ts @@ -29,11 +29,8 @@ export async function createVitest(mode: VitestRunMode, options: UserConfig, vit const server = await createServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root }))) - // optimizer needs .listen() to be called - if (ctx.config.api?.port || ctx.config.deps?.optimizer?.web?.enabled || ctx.config.deps?.optimizer?.ssr?.enabled) + if (ctx.config.api?.port) await server.listen() - else - await server.pluginContainer.buildStart({}) return ctx } diff --git a/packages/vitest/src/node/plugins/index.ts b/packages/vitest/src/node/plugins/index.ts index 5004a8c87d22..e3f11a49261e 100644 --- a/packages/vitest/src/node/plugins/index.ts +++ b/packages/vitest/src/node/plugins/index.ts @@ -57,7 +57,7 @@ export async function VitestPlugin(options: UserConfig = {}, ctx = new Vitest('t ;(options as ResolvedConfig).defines = defines - let open: string | boolean | undefined + let open: string | boolean | undefined = false if (testConfig.ui && testConfig.open) open = testConfig.uiBase ?? '/__vitest__/' diff --git a/packages/vitest/src/node/plugins/workspace.ts b/packages/vitest/src/node/plugins/workspace.ts index ea291ad41331..91f60af4dc04 100644 --- a/packages/vitest/src/node/plugins/workspace.ts +++ b/packages/vitest/src/node/plugins/workspace.ts @@ -70,6 +70,7 @@ export function WorkspaceVitestPlugin(project: WorkspaceProject, options: Worksp open: false, hmr: false, preTransformRequests: false, + middlewareMode: true, fs: { allow: resolveFsAllow( project.ctx.config.root, diff --git a/packages/vitest/src/node/workspace.ts b/packages/vitest/src/node/workspace.ts index 9a41650eef5b..bbf797a6cb13 100644 --- a/packages/vitest/src/node/workspace.ts +++ b/packages/vitest/src/node/workspace.ts @@ -46,11 +46,8 @@ export async function initializeProject(workspacePath: string | number, ctx: Vit const server = await createServer(config) - // optimizer needs .listen() to be called - if (ctx.config.api?.port || project.config.deps?.optimizer?.web?.enabled || project.config.deps?.optimizer?.ssr?.enabled) + if (ctx.config.api?.port) await server.listen() - else - await server.pluginContainer.buildStart({}) return project } diff --git a/packages/vitest/src/types/config.ts b/packages/vitest/src/types/config.ts index 7a40bd320d6d..6763cc938899 100644 --- a/packages/vitest/src/types/config.ts +++ b/packages/vitest/src/types/config.ts @@ -1,4 +1,4 @@ -import type { AliasOptions, CommonServerOptions, DepOptimizationConfig } from 'vite' +import type { AliasOptions, DepOptimizationConfig, ServerOptions } from 'vite' import type { PrettyFormatOptions } from 'pretty-format' import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers' import type { SequenceHooks, SequenceSetupFiles } from '@vitest/runner' @@ -23,7 +23,7 @@ export type VitestEnvironment = BuiltinEnvironment | (string & Record +export type ApiConfig = Pick export type { JSDOMOptions, HappyDOMOptions } diff --git a/test/core/package.json b/test/core/package.json index 998f1603a476..5a03728d28cb 100644 --- a/test/core/package.json +++ b/test/core/package.json @@ -3,6 +3,7 @@ "private": true, "scripts": { "test": "vitest", + "dev": "vite", "coverage": "vitest run --coverage" }, "devDependencies": { diff --git a/test/core/vitest.config.ts b/test/core/vite.config.ts similarity index 98% rename from test/core/vitest.config.ts rename to test/core/vite.config.ts index 03a6bec0c909..ff4e8cdc2635 100644 --- a/test/core/vitest.config.ts +++ b/test/core/vite.config.ts @@ -41,6 +41,9 @@ export default defineConfig({ { find: /^inline-lib$/, replacement: resolve(__dirname, 'projects', 'inline-lib') }, ], }, + server: { + port: 3022, + }, test: { name: 'core', exclude: ['**/fixtures/**', '**/vm-wasm.test.ts', ...defaultExclude], From b0dc4bb71922b3836180697301e563c8eac25bda Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Fri, 8 Sep 2023 11:58:04 +0300 Subject: [PATCH 2/4] chore: cleanup --- packages/vitest/src/node/config.ts | 8 ++------ packages/vitest/src/node/create.ts | 11 +++++++++++ packages/vitest/src/node/logger.ts | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 4682d7af632c..ea8219b86f83 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -27,11 +27,7 @@ export function resolveApiServerConfig( ): ApiConfig | undefined { let api: ApiConfig | undefined - const optimizer = options.deps?.optimizer - const optimizerEnabled = optimizer?.web?.enabled !== false || optimizer?.ssr?.enabled !== false - const needApi = options.ui || optimizerEnabled - - if (needApi && !options.api) + if (options.ui && !options.api) api = { port: defaultPort } else if (options.api === true) api = { port: defaultPort } @@ -53,7 +49,7 @@ export function resolveApiServerConfig( } if (api) { - if (!api.port) + if (!api.port && !api.middlewareMode) api.port = defaultPort } else { diff --git a/packages/vitest/src/node/create.ts b/packages/vitest/src/node/create.ts index e9d72c0edc62..be82d23f365e 100644 --- a/packages/vitest/src/node/create.ts +++ b/packages/vitest/src/node/create.ts @@ -27,10 +27,21 @@ export async function createVitest(mode: VitestRunMode, options: UserConfig, vit plugins: await VitestPlugin(options, ctx), } + // Vite prints an error (https://github.com/vitejs/vite/issues/14328) + // But Vitest works correctly either way + const error = console.error + console.error = (...args: any[]) => { + if (typeof args[0] === 'string' && args[0].includes('WebSocket server error:')) + return + error(...args) + } + const server = await createServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root }))) if (ctx.config.api?.port) await server.listen() + console.error = error + return ctx } diff --git a/packages/vitest/src/node/logger.ts b/packages/vitest/src/node/logger.ts index 76ee78cb8264..bd18b30861f4 100644 --- a/packages/vitest/src/node/logger.ts +++ b/packages/vitest/src/node/logger.ts @@ -139,7 +139,7 @@ export class Logger { if (this.ctx.config.ui) this.log(c.dim(c.green(` UI started at http://${this.ctx.config.api?.host || 'localhost'}:${c.bold(`${this.ctx.server.config.server.port}`)}${this.ctx.config.uiBase}`))) - else if (this.ctx.config.api) + else if (this.ctx.config.api?.port) this.log(c.dim(c.green(` API started at http://${this.ctx.config.api?.host || 'localhost'}:${c.bold(`${this.ctx.config.api.port}`)}`))) if (this.ctx.coverageProvider) From 363548654bd774bda10d187efdf1129375428311 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Fri, 8 Sep 2023 12:12:08 +0300 Subject: [PATCH 3/4] chore: cleanup --- packages/vitest/src/integrations/browser/server.ts | 3 +++ packages/vitest/src/node/workspace.ts | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/vitest/src/integrations/browser/server.ts b/packages/vitest/src/integrations/browser/server.ts index 63aeaf74a77d..6870c2bab68f 100644 --- a/packages/vitest/src/integrations/browser/server.ts +++ b/packages/vitest/src/integrations/browser/server.ts @@ -36,6 +36,9 @@ export async function createBrowserServer(project: WorkspaceProject, configFile: port: defaultBrowserPort, } + // browser never runs in middleware mode + server.middlewareMode = false + config.server = server config.server.fs ??= {} config.server.fs.allow = config.server.fs.allow || [] diff --git a/packages/vitest/src/node/workspace.ts b/packages/vitest/src/node/workspace.ts index bbf797a6cb13..9348d393a658 100644 --- a/packages/vitest/src/node/workspace.ts +++ b/packages/vitest/src/node/workspace.ts @@ -44,10 +44,7 @@ export async function initializeProject(workspacePath: string | number, ctx: Vit ], } - const server = await createServer(config) - - if (ctx.config.api?.port) - await server.listen() + await createServer(config) return project } From ccf618d0d1b1304bc41b9bfcdc8aa57cf3a1ef1e Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Fri, 8 Sep 2023 12:14:32 +0300 Subject: [PATCH 4/4] chore: cleanup --- packages/vitest/src/node/create.ts | 16 +++------------- packages/vitest/src/node/vite.ts | 21 +++++++++++++++++++++ packages/vitest/src/node/workspace.ts | 4 ++-- 3 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 packages/vitest/src/node/vite.ts diff --git a/packages/vitest/src/node/create.ts b/packages/vitest/src/node/create.ts index be82d23f365e..82a8f8f62d81 100644 --- a/packages/vitest/src/node/create.ts +++ b/packages/vitest/src/node/create.ts @@ -1,11 +1,12 @@ import { resolve } from 'pathe' -import { createServer, mergeConfig } from 'vite' +import { mergeConfig } from 'vite' import type { InlineConfig as ViteInlineConfig, UserConfig as ViteUserConfig } from 'vite' import { findUp } from 'find-up' import type { UserConfig, VitestRunMode } from '../types' import { configFiles } from '../constants' import { Vitest } from './core' import { VitestPlugin } from './plugins' +import { createViteServer } from './vite' export async function createVitest(mode: VitestRunMode, options: UserConfig, viteOverrides: ViteUserConfig = {}) { const ctx = new Vitest(mode) @@ -27,21 +28,10 @@ export async function createVitest(mode: VitestRunMode, options: UserConfig, vit plugins: await VitestPlugin(options, ctx), } - // Vite prints an error (https://github.com/vitejs/vite/issues/14328) - // But Vitest works correctly either way - const error = console.error - console.error = (...args: any[]) => { - if (typeof args[0] === 'string' && args[0].includes('WebSocket server error:')) - return - error(...args) - } - - const server = await createServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root }))) + const server = await createViteServer(mergeConfig(config, mergeConfig(viteOverrides, { root: options.root }))) if (ctx.config.api?.port) await server.listen() - console.error = error - return ctx } diff --git a/packages/vitest/src/node/vite.ts b/packages/vitest/src/node/vite.ts new file mode 100644 index 000000000000..4138d3b1fc8b --- /dev/null +++ b/packages/vitest/src/node/vite.ts @@ -0,0 +1,21 @@ +import type { InlineConfig } from 'vite' +import { createServer } from 'vite' + +export async function createViteServer(inlineConfig: InlineConfig) { + // Vite prints an error (https://github.com/vitejs/vite/issues/14328) + // But Vitest works correctly either way + const error = console.error + console.error = (...args: any[]) => { + if (typeof args[0] === 'string' && args[0].includes('WebSocket server error:')) + return + error(...args) + } + + const server = await createServer({ + logLevel: 'error', + ...inlineConfig, + }) + + console.error = error + return server +} diff --git a/packages/vitest/src/node/workspace.ts b/packages/vitest/src/node/workspace.ts index 9348d393a658..02a3ce48d4e4 100644 --- a/packages/vitest/src/node/workspace.ts +++ b/packages/vitest/src/node/workspace.ts @@ -2,7 +2,6 @@ import { promises as fs } from 'node:fs' import fg from 'fast-glob' import mm from 'micromatch' import { dirname, relative, resolve, toNamespacedPath } from 'pathe' -import { createServer } from 'vite' import type { ViteDevServer, InlineConfig as ViteInlineConfig } from 'vite' import { ViteNodeRunner } from 'vite-node/client' import { ViteNodeServer } from 'vite-node/server' @@ -14,6 +13,7 @@ import type { BrowserProvider } from '../types/browser' import { getBrowserProvider } from '../integrations/browser' import { isBrowserEnabled, resolveConfig } from './config' import { WorkspaceVitestPlugin } from './plugins/workspace' +import { createViteServer } from './vite' interface InitializeProjectOptions extends UserWorkspaceConfig { workspaceConfigPath: string @@ -44,7 +44,7 @@ export async function initializeProject(workspacePath: string | number, ctx: Vit ], } - await createServer(config) + await createViteServer(config) return project }