mirror of
https://github.com/cloudflare/vinext.git
synced 2026-09-14 19:04:59 +08:00
test: parallelize the integration suite (#3201)
This commit is contained in:
@@ -3,10 +3,10 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { createBuilder } from "vite";
|
||||
import { afterAll, describe, expect, it, vi } from "vite-plus/test";
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from "vite-plus/test";
|
||||
import vinext from "../packages/vinext/src/index.js";
|
||||
import { runPrerender } from "../packages/vinext/src/build/run-prerender.js";
|
||||
import { APP_FIXTURE_DIR } from "./helpers.js";
|
||||
import { APP_FIXTURE_DIR, createIsolatedFixture, testCacheDir } from "./helpers.js";
|
||||
|
||||
type BuiltAppHandler = (request: Request) => Promise<Response | string | null | undefined>;
|
||||
|
||||
@@ -33,17 +33,29 @@ function readAllJs(dir: string): string {
|
||||
}
|
||||
|
||||
describe("App Router Production build", () => {
|
||||
const outDir = path.resolve(APP_FIXTURE_DIR, "dist");
|
||||
let fixtureDir: string;
|
||||
let outDir: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
fixtureDir = await createIsolatedFixture(
|
||||
APP_FIXTURE_DIR,
|
||||
"vinext-app-production-build-",
|
||||
undefined,
|
||||
path.join(APP_FIXTURE_DIR, "node_modules"),
|
||||
);
|
||||
outDir = path.join(fixtureDir, "dist");
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
fs.rmSync(outDir, { recursive: true, force: true });
|
||||
fs.rmSync(fixtureDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it("produces RSC/SSR/client bundles via vite build", async () => {
|
||||
const builder = await createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
plugins: [vinext({ appDir: fixtureDir })],
|
||||
logLevel: "silent",
|
||||
});
|
||||
await builder.buildApp();
|
||||
@@ -193,9 +205,10 @@ describe("App Router Production build", () => {
|
||||
process.env.__VINEXT_SHARED_BUILD_ID = sharedBuildId;
|
||||
try {
|
||||
const builder = await createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
plugins: [vinext({ appDir: fixtureDir })],
|
||||
logLevel: "silent",
|
||||
});
|
||||
await builder.buildApp();
|
||||
@@ -223,9 +236,10 @@ describe("App Router Production build", () => {
|
||||
process.env.__VINEXT_SHARED_PRERENDER_SECRET = sharedSecret;
|
||||
try {
|
||||
const builder = await createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
plugins: [vinext({ appDir: fixtureDir })],
|
||||
logLevel: "silent",
|
||||
});
|
||||
await builder.buildApp();
|
||||
@@ -254,11 +268,12 @@ describe("App Router Production build", () => {
|
||||
process.env.__VINEXT_SHARED_BUILD_ID = sharedBuildId;
|
||||
try {
|
||||
const builder = await createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
// generateBuildId returning null falls back to a random UUID per
|
||||
// instance; the shared ID must still be adopted.
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR, nextConfig: { generateBuildId: () => null } })],
|
||||
plugins: [vinext({ appDir: fixtureDir, nextConfig: { generateBuildId: () => null } })],
|
||||
logLevel: "silent",
|
||||
});
|
||||
await builder.buildApp();
|
||||
@@ -287,9 +302,10 @@ describe("App Router Production build", () => {
|
||||
process.env.__VINEXT_SHARED_RSC_COMPATIBILITY_ID = sharedCompatId;
|
||||
try {
|
||||
const builder = await createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
plugins: [vinext({ appDir: fixtureDir })],
|
||||
logLevel: "silent",
|
||||
});
|
||||
await builder.buildApp();
|
||||
@@ -581,9 +597,10 @@ export default async function OpenGraphImage() {
|
||||
const { preview } = await import("vite");
|
||||
|
||||
const previewServer = await preview({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
plugins: [vinext({ appDir: fixtureDir })],
|
||||
preview: { port: 0 },
|
||||
logLevel: "silent",
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
getPagesClientAssets,
|
||||
setPagesClientAssets,
|
||||
} from "../packages/vinext/src/server/pages-client-assets.js";
|
||||
import { APP_FIXTURE_DIR, createIsolatedFixture } from "./helpers.js";
|
||||
import { APP_FIXTURE_DIR, createIsolatedFixture, testCacheDir } from "./helpers.js";
|
||||
|
||||
const ROOT_LAYOUT_NOT_FOUND_REDIRECT_FIXTURE_DIR = path.resolve(
|
||||
import.meta.dirname,
|
||||
@@ -296,6 +296,7 @@ describe("App Router Production server (startProdServer)", () => {
|
||||
// Build the app-basic fixture to the default dist/ directory
|
||||
const builder = await createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
cacheDir: testCacheDir(APP_FIXTURE_DIR),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
logLevel: "silent",
|
||||
|
||||
@@ -4,7 +4,7 @@ import path from "node:path";
|
||||
import { type ViteDevServer } from "vite";
|
||||
import { beforeAll, afterAll, describe, expect, it } from "vite-plus/test";
|
||||
import vinext from "../packages/vinext/src/index.js";
|
||||
import { APP_FIXTURE_DIR, fetchHtml, RSC_ENTRIES } from "./helpers.js";
|
||||
import { APP_FIXTURE_DIR, fetchHtml, RSC_ENTRIES, testCacheDir } from "./helpers.js";
|
||||
|
||||
describe("RSC plugin auto-registration", () => {
|
||||
let server: ViteDevServer;
|
||||
@@ -18,6 +18,7 @@ describe("RSC plugin auto-registration", () => {
|
||||
const { createServer } = await import("vite");
|
||||
server = await createServer({
|
||||
root: APP_FIXTURE_DIR,
|
||||
cacheDir: testCacheDir(APP_FIXTURE_DIR),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
optimizeDeps: { holdUntilCrawlEnd: true },
|
||||
@@ -53,6 +54,7 @@ describe("RSC plugin auto-registration", () => {
|
||||
const { createServer } = await import("vite");
|
||||
const deploymentServer = await createServer({
|
||||
root: APP_FIXTURE_DIR,
|
||||
cacheDir: testCacheDir(APP_FIXTURE_DIR),
|
||||
configFile: false,
|
||||
plugins: [
|
||||
vinext({
|
||||
@@ -91,6 +93,7 @@ describe("RSC plugin auto-registration", () => {
|
||||
// Should work without errors (no duplicate registration).
|
||||
const serverWithExplicitRsc = await createServer({
|
||||
root: APP_FIXTURE_DIR,
|
||||
cacheDir: testCacheDir(APP_FIXTURE_DIR),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR, rsc: false }), rsc({ entries: RSC_ENTRIES })],
|
||||
optimizeDeps: { holdUntilCrawlEnd: true },
|
||||
@@ -117,6 +120,7 @@ describe("RSC plugin auto-registration", () => {
|
||||
await expect(
|
||||
createServer({
|
||||
root: APP_FIXTURE_DIR,
|
||||
cacheDir: testCacheDir(APP_FIXTURE_DIR),
|
||||
configFile: false,
|
||||
plugins: [rsc({ entries: RSC_ENTRIES }), vinext({ appDir: APP_FIXTURE_DIR, rsc: false })],
|
||||
optimizeDeps: { holdUntilCrawlEnd: true },
|
||||
@@ -136,6 +140,7 @@ describe("RSC plugin auto-registration", () => {
|
||||
await expect(
|
||||
createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
cacheDir: testCacheDir(APP_FIXTURE_DIR),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR }), rsc({ entries: RSC_ENTRIES })],
|
||||
logLevel: "silent",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
import http, { type IncomingHttpHeaders } from "node:http";
|
||||
import fsSync from "node:fs";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import { pathToFileURL } from "node:url";
|
||||
@@ -15,6 +16,7 @@ import { createServer, build, type ViteDevServer } from "vite";
|
||||
import vinext from "../packages/vinext/src/index.js";
|
||||
import path from "node:path";
|
||||
import type { NextConfigInput } from "../packages/vinext/src/config/next-config.js";
|
||||
import { afterAll } from "vite-plus/test";
|
||||
|
||||
// ── Fixture paths ─────────────────────────────────────────────
|
||||
export const PAGES_FIXTURE_DIR = path.resolve(import.meta.dirname, "./fixtures/pages-basic");
|
||||
@@ -35,6 +37,36 @@ export const RSC_ENTRIES = {
|
||||
client: "virtual:vinext-app-browser-entry",
|
||||
} as const;
|
||||
|
||||
const testCacheDirs = new Map<string, string>();
|
||||
let testCacheRoot: string | undefined;
|
||||
|
||||
if (process.env.VINEXT_PARALLEL_INTEGRATION === "true") {
|
||||
afterAll(() => {
|
||||
if (testCacheRoot) fsSync.rmSync(testCacheRoot, { recursive: true, force: true });
|
||||
testCacheDirs.clear();
|
||||
testCacheRoot = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
export function testCacheDir(fixtureDir: string): string | undefined {
|
||||
if (process.env.VINEXT_PARALLEL_INTEGRATION !== "true") return undefined;
|
||||
|
||||
const fixture = path.resolve(fixtureDir);
|
||||
let cacheDir = testCacheDirs.get(fixture);
|
||||
if (!cacheDir) {
|
||||
if (!testCacheRoot) {
|
||||
testCacheRoot = path.resolve(
|
||||
import.meta.dirname,
|
||||
`../node_modules/.vite-vitest-${process.pid}`,
|
||||
);
|
||||
fsSync.mkdirSync(testCacheRoot);
|
||||
}
|
||||
cacheDir = path.join(testCacheRoot, String(testCacheDirs.size));
|
||||
testCacheDirs.set(fixture, cacheDir);
|
||||
}
|
||||
return cacheDir;
|
||||
}
|
||||
|
||||
// ── Server lifecycle helper ───────────────────────────────────
|
||||
|
||||
export type TestServerResult = {
|
||||
@@ -86,6 +118,7 @@ export async function startFixtureServer(
|
||||
|
||||
const server = await createServer({
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins,
|
||||
publicDir: opts?.publicDir,
|
||||
@@ -263,6 +296,7 @@ export async function buildPagesFixture(
|
||||
// (hybrid); we only want the Pages Router SSR bundle here.
|
||||
await build({
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ disableAppRouter: true, nextConfig })],
|
||||
logLevel: "silent",
|
||||
@@ -299,6 +333,7 @@ export async function buildAppFixture(
|
||||
const { createBuilder } = await import("vite");
|
||||
const builder = await createBuilder({
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: fixtureDir, rscOutDir, ssrOutDir, clientOutDir, nextConfig })],
|
||||
logLevel: "silent",
|
||||
@@ -349,6 +384,7 @@ export async function buildCloudflareAppFixture(fixtureDir: string): Promise<{
|
||||
const { createBuilder } = await import("vite");
|
||||
const builder = await createBuilder({
|
||||
root: tmpDir,
|
||||
cacheDir: testCacheDir(tmpDir),
|
||||
configFile: false,
|
||||
plugins: [
|
||||
vinext({ appDir: tmpDir }),
|
||||
|
||||
@@ -31,7 +31,13 @@ import path from "node:path";
|
||||
import { describe, it, expect, beforeAll, afterAll } from "vite-plus/test";
|
||||
import { createBuilder, preview, type ViteDevServer } from "vite-plus";
|
||||
import vinext from "../../packages/vinext/src/index.js";
|
||||
import { APP_FIXTURE_DIR, startFixtureServer, fetchHtml } from "../helpers.js";
|
||||
import {
|
||||
APP_FIXTURE_DIR,
|
||||
createIsolatedFixture,
|
||||
startFixtureServer,
|
||||
fetchHtml,
|
||||
testCacheDir,
|
||||
} from "../helpers.js";
|
||||
|
||||
describe("Next.js compat: global-error", () => {
|
||||
let server: ViteDevServer;
|
||||
@@ -273,23 +279,31 @@ describe("Next.js compat: global-error", () => {
|
||||
});
|
||||
|
||||
describe("Next.js compat: global-error (production preview)", () => {
|
||||
const outDir = path.resolve(APP_FIXTURE_DIR, "dist");
|
||||
let fixtureDir: string;
|
||||
let previewServer: Awaited<ReturnType<typeof preview>>;
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
fixtureDir = await createIsolatedFixture(
|
||||
APP_FIXTURE_DIR,
|
||||
"vinext-global-error-",
|
||||
undefined,
|
||||
path.join(APP_FIXTURE_DIR, "node_modules"),
|
||||
);
|
||||
const builder = await createBuilder({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
plugins: [vinext({ appDir: fixtureDir })],
|
||||
logLevel: "silent",
|
||||
});
|
||||
await builder.buildApp();
|
||||
|
||||
previewServer = await preview({
|
||||
root: APP_FIXTURE_DIR,
|
||||
root: fixtureDir,
|
||||
cacheDir: testCacheDir(fixtureDir),
|
||||
configFile: false,
|
||||
plugins: [vinext({ appDir: APP_FIXTURE_DIR })],
|
||||
plugins: [vinext({ appDir: fixtureDir })],
|
||||
preview: { port: 0 },
|
||||
logLevel: "silent",
|
||||
});
|
||||
@@ -303,7 +317,7 @@ describe("Next.js compat: global-error (production preview)", () => {
|
||||
|
||||
afterAll(() => {
|
||||
previewServer?.httpServer.close();
|
||||
fs.rmSync(outDir, { recursive: true, force: true });
|
||||
fs.rmSync(fixtureDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it("server component throw without local error.tsx renders global-error with 500", async () => {
|
||||
|
||||
+26
-11
@@ -13,7 +13,12 @@ import fs from "node:fs";
|
||||
import { createServer, type Server } from "node:http";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { buildPagesFixture, buildAppFixture, buildCloudflareAppFixture } from "./helpers.js";
|
||||
import {
|
||||
buildPagesFixture,
|
||||
buildAppFixture,
|
||||
buildCloudflareAppFixture,
|
||||
createIsolatedFixture,
|
||||
} from "./helpers.js";
|
||||
import {
|
||||
extractRscPayloadFromPrerenderedHtml,
|
||||
resolveParentParams,
|
||||
@@ -2015,25 +2020,35 @@ describe("prerenderApp — cacheComponents PPR fallback-shell artifacts", () =>
|
||||
// ─── runPrerender — output: 'export' wiring ───────────────────────────────────
|
||||
|
||||
describe("runPrerender — output: 'export' wiring", () => {
|
||||
let fixtureDir: string;
|
||||
let pagesBundlePath: string;
|
||||
let exportNextConfig: Awaited<
|
||||
ReturnType<typeof import("../packages/vinext/src/config/next-config.js").resolveNextConfig>
|
||||
>;
|
||||
|
||||
beforeAll(async () => {
|
||||
// Build pages-basic to a fresh tmpdir — no fixture copying needed.
|
||||
fixtureDir = await createIsolatedFixture(
|
||||
PAGES_FIXTURE,
|
||||
"vinext-run-prerender-",
|
||||
undefined,
|
||||
path.join(PAGES_FIXTURE, "node_modules"),
|
||||
);
|
||||
// Pass the bundle path and resolved config to runPrerender so it
|
||||
// exercises output: 'export' without touching the real next.config.mjs.
|
||||
pagesBundlePath = await buildPagesFixture(PAGES_FIXTURE);
|
||||
const { resolveNextConfig } = await import("../packages/vinext/src/config/next-config.js");
|
||||
exportNextConfig = await resolveNextConfig({ output: "export" }, PAGES_FIXTURE);
|
||||
exportNextConfig = await resolveNextConfig({ output: "export" }, fixtureDir);
|
||||
}, 120_000);
|
||||
|
||||
afterAll(() => {
|
||||
fs.rmSync(fixtureDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it("throws when next.config output: 'export' and SSR routes exist", async () => {
|
||||
const { runPrerender } = await import("../packages/vinext/src/build/run-prerender.js");
|
||||
await expect(
|
||||
runPrerender({
|
||||
root: PAGES_FIXTURE,
|
||||
root: fixtureDir,
|
||||
nextConfig: exportNextConfig,
|
||||
pagesBundlePath,
|
||||
}),
|
||||
@@ -2041,7 +2056,7 @@ describe("runPrerender — output: 'export' wiring", () => {
|
||||
});
|
||||
|
||||
it("does not reload disk config when the caller supplies resolved config", async () => {
|
||||
const configPath = path.join(PAGES_FIXTURE, "next.config.mjs");
|
||||
const configPath = path.join(fixtureDir, "next.config.mjs");
|
||||
const originalConfig = fs.readFileSync(configPath, "utf-8");
|
||||
|
||||
try {
|
||||
@@ -2050,11 +2065,11 @@ describe("runPrerender — output: 'export' wiring", () => {
|
||||
import("../packages/vinext/src/build/run-prerender.js"),
|
||||
import("../packages/vinext/src/config/next-config.js"),
|
||||
]);
|
||||
const nextConfig = await resolveNextConfig({ output: "export" }, PAGES_FIXTURE);
|
||||
const nextConfig = await resolveNextConfig({ output: "export" }, fixtureDir);
|
||||
|
||||
await expect(
|
||||
runPrerender({
|
||||
root: PAGES_FIXTURE,
|
||||
root: fixtureDir,
|
||||
nextConfig,
|
||||
pagesBundlePath,
|
||||
}),
|
||||
@@ -2065,7 +2080,7 @@ describe("runPrerender — output: 'export' wiring", () => {
|
||||
});
|
||||
|
||||
it("does not rewrite the Worker entry when prerender validation fails", async () => {
|
||||
const workerEntry = path.join(PAGES_FIXTURE, "dist", "server", "index.js");
|
||||
const workerEntry = path.join(fixtureDir, "dist", "server", "index.js");
|
||||
const source = 'export default { fetch() { return new Response("unchanged"); } };\n';
|
||||
fs.mkdirSync(path.dirname(workerEntry), { recursive: true });
|
||||
fs.writeFileSync(workerEntry, source, "utf-8");
|
||||
@@ -2074,7 +2089,7 @@ describe("runPrerender — output: 'export' wiring", () => {
|
||||
const { runPrerender } = await import("../packages/vinext/src/build/run-prerender.js");
|
||||
await expect(
|
||||
runPrerender({
|
||||
root: PAGES_FIXTURE,
|
||||
root: fixtureDir,
|
||||
nextConfig: exportNextConfig,
|
||||
pagesBundlePath,
|
||||
}),
|
||||
@@ -2082,7 +2097,7 @@ describe("runPrerender — output: 'export' wiring", () => {
|
||||
|
||||
expect(fs.readFileSync(workerEntry, "utf-8")).toBe(source);
|
||||
} finally {
|
||||
fs.rmSync(path.join(PAGES_FIXTURE, "dist"), { recursive: true, force: true });
|
||||
fs.rmSync(path.join(fixtureDir, "dist"), { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2090,7 +2105,7 @@ describe("runPrerender — output: 'export' wiring", () => {
|
||||
const { runPrerender } = await import("../packages/vinext/src/build/run-prerender.js");
|
||||
await expect(
|
||||
runPrerender({
|
||||
root: PAGES_FIXTURE,
|
||||
root: fixtureDir,
|
||||
nextConfig: exportNextConfig,
|
||||
pagesBundlePath,
|
||||
}),
|
||||
|
||||
+8
-6
@@ -177,9 +177,8 @@ export default defineConfig({
|
||||
include: ["tests/**/*.test.ts", "scripts/**/*.test.ts"],
|
||||
exclude: [
|
||||
"tests/fixtures/**/node_modules/**",
|
||||
// Integration tests: spin up Vite dev servers against shared fixture
|
||||
// dirs. Must run serially to avoid Vite deps optimizer cache races
|
||||
// (node_modules/.vite/*) that produce "outdated pre-bundle" 500s.
|
||||
// Integration tests spin up Vite dev servers against shared fixture
|
||||
// dirs and use per-worker optimizer caches in their own project.
|
||||
// When adding a test that calls startFixtureServer() or createServer(),
|
||||
// move it here.
|
||||
"tests/app-router-client-preloading.test.ts",
|
||||
@@ -241,6 +240,9 @@ export default defineConfig({
|
||||
},
|
||||
test: {
|
||||
name: "integration",
|
||||
env: {
|
||||
VINEXT_PARALLEL_INTEGRATION: "true",
|
||||
},
|
||||
// MSW is intentionally NOT installed in the integration project.
|
||||
// Integration tests spin up in-process HTTP servers and fixture
|
||||
// dev servers and exercise them via `fetch("http://127.0.0.1:<port>/...")`.
|
||||
@@ -305,9 +307,9 @@ export default defineConfig({
|
||||
"tests/nextjs-compat/**/*.test.ts",
|
||||
],
|
||||
testTimeout: 30000,
|
||||
// Serial execution prevents Vite deps optimizer cache races when
|
||||
// multiple test files share the same fixture directory.
|
||||
fileParallelism: false,
|
||||
fileParallelism: true,
|
||||
maxWorkers: 3,
|
||||
sequence: { groupOrder: 1 },
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user