chore(build,test): split desktop/mobile from default build; share vitest worker budget
- pnpm build now excludes @fusion/desktop and @fusion/mobile by default (recursive build still available as pnpm build:all). Saves time on workspace-wide builds that don't need the native shells. - Hoist the per-package max-worker computation into a shared packages/core/src/__test-utils__/vitest-workers.ts util. Every vitest.config.ts now calls computeMaxWorkers(), which honors VITEST_MAX_WORKERS, FUSION_TEST_TOTAL_WORKERS, and a per-config defaultCap, clamped to cpus-1. - pnpm test sets VITEST_MAX_WORKERS=2 so the workspace run keeps total fan-out modest with --workspace-concurrency=2. - Switch dashboard vitest pool from forks to threads so jsdom/React suites share a V8 heap instead of duplicating ~500MB per worker. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
45
packages/core/src/__test-utils__/vitest-workers.ts
Normal file
45
packages/core/src/__test-utils__/vitest-workers.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { cpus } from "node:os";
|
||||
|
||||
interface ComputeMaxWorkersOptions {
|
||||
defaultCap?: number;
|
||||
}
|
||||
|
||||
// Shared worker-budget computation for every package's vitest.config.
|
||||
//
|
||||
// Resolution order:
|
||||
// 1. VITEST_MAX_WORKERS — explicit per-run override, wins unconditionally.
|
||||
// 2. FUSION_TEST_TOTAL_WORKERS — global budget across the workspace, divided
|
||||
// by FUSION_TEST_CONCURRENCY (default 1). Lets `pnpm -r` runs cap total
|
||||
// fan-out instead of multiplying per package.
|
||||
// 3. defaultCap — small ceiling (2 by default) so a single package run on a
|
||||
// high-core machine stays gentle.
|
||||
// All paths clamp to (cpus - 1) so we never oversubscribe.
|
||||
export function computeMaxWorkers(options: ComputeMaxWorkersOptions = {}): number {
|
||||
const { defaultCap = 2 } = options;
|
||||
|
||||
const cpuCap = Math.max(1, cpus().length - 1);
|
||||
|
||||
const explicit = Number.parseInt(process.env.VITEST_MAX_WORKERS ?? "", 10);
|
||||
if (Number.isFinite(explicit) && explicit > 0) {
|
||||
const clamped = Math.min(Math.max(1, explicit), cpuCap);
|
||||
process.env.VITEST_MAX_WORKERS = String(clamped);
|
||||
return clamped;
|
||||
}
|
||||
|
||||
const totalBudget = Number.parseInt(process.env.FUSION_TEST_TOTAL_WORKERS ?? "", 10);
|
||||
const concurrency = Math.max(
|
||||
1,
|
||||
Number.parseInt(process.env.FUSION_TEST_CONCURRENCY ?? "1", 10) || 1,
|
||||
);
|
||||
|
||||
let workers: number;
|
||||
if (Number.isFinite(totalBudget) && totalBudget > 0) {
|
||||
workers = Math.max(1, Math.floor(totalBudget / concurrency));
|
||||
} else {
|
||||
workers = defaultCap;
|
||||
}
|
||||
|
||||
workers = Math.min(workers, cpuCap);
|
||||
process.env.VITEST_MAX_WORKERS = String(workers);
|
||||
return workers;
|
||||
}
|
||||
@@ -1,14 +1,8 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { resolve } from "node:path";
|
||||
import { cpus } from "node:os";
|
||||
import { computeMaxWorkers } from "./src/__test-utils__/vitest-workers";
|
||||
|
||||
// Keep worker fan-out conservative by default. Over-subscribing threads can
|
||||
// starve Vitest's worker RPC channel and trigger flaky "onTaskUpdate" timeouts
|
||||
// under heavy SQLite test load.
|
||||
const defaultMaxWorkers = Math.min(4, Math.max(1, cpus().length - 1));
|
||||
const requestedMaxWorkers = Number.parseInt(process.env.VITEST_MAX_WORKERS ?? String(defaultMaxWorkers), 10);
|
||||
const maxWorkers = Math.max(1, Number.isFinite(requestedMaxWorkers) ? requestedMaxWorkers : defaultMaxWorkers);
|
||||
process.env.VITEST_MAX_WORKERS = String(maxWorkers);
|
||||
const maxWorkers = computeMaxWorkers();
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
|
||||
Reference in New Issue
Block a user