@cldmv/最差跑者
@cldmv/最差跑者 是相继的 维特 所以大型的测试套房 从来不需要符合一个维特进程的内存 它一次运行一个文件或者在一个平行的工人池中运行一个文件,给重文件自己一个堆积的天花板或者一个独行槽,并打印出一个结果,内存使用和持续时间的综合摘要到结尾.
覆盖范围也不安全:每个文件都写一个覆盖blob和一个 vitest --mergeReports 步骤将它们合并为一份报告,后面有一个最坏的覆盖表。 跑步者自动检测您的 Vitest 配置, 转发每个标准 Vitest 旗帜不变 vitest-runner CLI或作为一个方案 run() 来自无害环境管理和共同司法体系的API.
大套房,小流程:每个测试文件都得到自己的Vitest,结果作为一跑回来.
曰如何是新来
最近:v1.6.1(2026年11月)
engines.node设置到运行时间层 -v1.6.0 申报>=22.22.0,建筑和测试工具链地板.engines.node现在>=22.0.0,楼下chalk6个依赖,22.22.0个发展层搬到devEngines,所以更早的节点.js 22放出安装了跑道,没有EBADENGINE警告 警告他们.require()- 行为和选项保持不变(115号) (中文(简体) ).- 查看全 v1.6.1 更改日志
最近发布的
- 页:1 (2026年11月 - ) (中文(简体) )
--conditions=vitest-runner-dev发送require()改为src/index.cjs还有..engines.node升为>=22.22.0; 跑步行为不变(更改日志(中文(简体) ) - 页:1 (2026年10月)——开发工具依赖性更新:
tsup9, Vitest 5.0.5 and a (中文(简体) )katex覆盖两个 Deptabot 提醒; 构建的文件与 v1.5.5 字节相同(更改日志(中文(简体) ) - v1.5.5 (中文(简体) ) (2026年10月) — 不再开放
ENOTEMPTYvitest 5 模块缓存的启动出错:每个包有一个缓存目录,每个运行一个锁定文件检查,以及一个新的fsModuleCachePath选项(更改日志(中文(简体) ) - 页:1 (2026年10月)——开发工具依赖性更新(日语:
@cldmv/fix-headers2.2.0, (中文(简体) ),@cldmv/configs1.2.4;已公布的包件与v1.5.3相同(更改日志(中文(简体) )
完整的释放说明见 文件/更改日志/ 文件夹.
关键特性
- 在自己的孩子过程中运行每个测试文件, 一次一个或一个可配置的平行工人池
- 用于重文件的 Solo 插槽( S)
--solo-pattern和每个文件的上限(perFileHeapOverrides(中文(简体) ) - 通过blob-per-file +实现全覆盖模式
--mergeReports(没有OOM),有最糟糕的覆盖表 - 自动检测您的 vitest 配置; 必要时接受一个明确的路径
- 所有标准 Vitest CLI 旗都未更改转发
- 可用作 CLI 二进制 或作为 方案节点js API,带有可选 JSON 运行报告
- 每个测试文件的每个运行抓取目录( M)
VITEST_RUNNER_TMP编号 :makeRunTmpDir),出口时清理 - ES 模块的构建带有一个细小的 commonJS 条目
require()
* 安装
所需资源
- 节点.js 22.0.0或以后 (单位:千美元)
engines.node实值>=22.0.0,则chalk6 受抚养人)。 该软件包是一个ES模块并装入import。您安装的Vitest版本有自己的节点.js地板。 节点.js 20不支持从v1.5.3;停留在v1.5.1上. require("@cldmv/vitest-runner")加载 ES 模块同步构建,需要 Node.js QQ22.13.0; 在更古老的 Node.js 上,使用import()换句话说.- 开发这个软件包需要节点22.22.0或以后(
devEngines) (中文(简体) ). vitest^ 1.0( 同类依赖, 安装在您的项目中)chalk(分散依赖——不需要采取行动)
安装
npm install --save-dev @cldmv/vitest-runner
或者在全球使用CLI:
npm install -g @cldmv/vitest-runner
QQ 快速启动
运行每一个发现 *.test.vitest.{js,mjs,cjs} 文件,每个文件在自己的进程中:
npx vitest-runner
运行 OOM 安全覆盖和现场进展栏:
npx vitest-runner --coverage-quiet
从代码 :
import { run } from "@cldmv/vitest-runner";
const code = await run({ testDir: "src/tests" });
process.exit(code);
全旗名单在 CLI 使用情况 和每个选项 程序化 API。 。 。 .
QCLI 使用量
vitest-runner [OPTIONS] [PATTERNS...]
运行中旗
| 旗帜 | 说明 |
|---|---|
--test-list <file> | 只运行 JSON 阵列文件中列出的文件, 而不是扫描 |
--file-pattern <regex> | 覆盖文件发现 regex( 默认 ): \.test\.vitest\.(?:js|mjs|cjs)$(中文(简体) ) |
--workers <n> | 平行工人人数( 默认 : 4 或者说 VITEST_WORKERS(中文(简体) ) |
--solo-pattern <pat> | 在工人池前运行匹配此路径的子串独奏文件( 一次一个); 可重复 |
--exclude <glob> | 目录 / 文件 glob, 相对 cwd,该发现从未进入(例如:. tmp/**; 可重复 |
--no-error-details | 隐藏内置错误块——仅在摘要中显示计数 |
--coverage-quiet | 符号 --coverage; 禁用每个文件的输出, 只显示实时进度栏和最后摘要 |
--log-file <path> | 写入所有输出到此文件的干净( ANSI- stripped) 副本 。 默认为 coverage/coverage-run.log 何时 --coverage-quiet 活动 |
--suppress-file-output | 在任意模式下禁止每个文件的跑者输出块 |
--suppress-passing-files | 隐藏 PASSED TEST FILES 最后摘要中的章节 |
--no-top-summary | 隐藏 TOP MEMORY USERS 财务报告和审定财务报表 TOP DURATION 摘要 |
--json | 打印 JSON 运行报表( 没有运行中文本输出) |
--blobs-dir <path> | 每个文件覆盖blobs的目录( 默认 : .vitest-coverage-blobs相对 cwd(中文(简体) ) |
--no-merge-reports | 制作覆盖块,但跳过合并和摘要,把它们留在 --blobs-dir 用于外部合并步骤 |
--keep-tmp | 保存此运行的抓取目录, 而不是在完成时删除 |
--scratch-dir <path> | 每个运行的抓取根,相对于 cwd (默认 : tmp/vitest-runner(中文(简体) ) |
--help, (中文(简体) ), -h | 打印此帮助并退出 |
测试模式
模式按 cwd下述任何形式的工作:
# Absolute or relative file path
vitest-runner src/tests/config/background.test.vitest.mjs
# Partial path or filename — matched against all discovered test files
vitest-runner background.test.vitest.mjs
vitest-runner config/background.test.vitest.mjs
# Directory — all test files inside it are run
vitest-runner src/tests/metadata
多种模式可以合并:
vitest-runner src/tests/config src/tests/metadata
维特传球旗
所有未识别旗帜均逐字转发给每个vitest儿童进程:
vitest-runner --reporter=verbose
vitest-runner -t "lazy materialization"
vitest-runner --coverage
vitest-runner --bail
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
VITEST_HEAP_MB | (无) | --max-old-space-size 每个儿童过程的上限 |
VITEST_WORKERS | 4 | 非索洛阶段最大平行工人档次(由 --workers(中文(简体) ) |
实例
# Run all test files discovered under the default testDir
vitest-runner
# Run all tests, filter by name
vitest-runner -t "should handle null input"
# Run a specific folder
vitest-runner src/tests/auth
# Run with coverage (blob + merge — OOM-safe)
vitest-runner --coverage
# Coverage with quiet output and live progress bar (ideal for CI)
vitest-runner --coverage --coverage-quiet
# Run only files listed in a JSON file
vitest-runner --test-list my-tests.json
# Use a custom file discovery pattern
vitest-runner --file-pattern '\.spec\.ts$'
# Run 2 workers, with certain files running solo first
vitest-runner --workers 2 --solo-pattern heavy/ --solo-pattern listener-cleanup/
# Skip scratch worktrees / build output when discovery walks the repo root
vitest-runner --exclude 'tmp/**' --exclude 'dist/**'
# Custom heap and worker count
VITEST_HEAP_MB=8192 vitest-runner --workers 2 src/tests/heavy
# Suppress error details in the summary
vitest-runner --no-error-details
# JSON output for automation
vitest-runner --json
# JSON output without top summary arrays
vitest-runner --json --no-top-summary
编程 API
import { run } from "@cldmv/vitest-runner";
// CommonJS
const { run } = require("@cldmv/vitest-runner");
require() 装入 ES 模块通过节点同步构建 require(esm),这需要Node.js >=22.13.0;在更古老的Node.js上,它投出一个清晰的 ERR_REQUIRE_ESM 错误,以及 import() 是装入软件包的方法.
对照本地的检出或工作空间副本而非已公布的软件包开发时, 运行节点 --conditions=vitest-runner-dev 这样 import 定义 src/ 条目(src/index.mjs和 require 改为 src/index.cjs,而不是建造 dist/。 。 。 .
run(options) → Promise<number | object>
运行测试套件,并以退出代码解决(0 都过去了, 1 = 任何失败),默认情况下. 何时 json: true 它返回结构化的 JSON 报告对象(包括 exitCode)而不是打印跑道文本输出.
import { run } from "@cldmv/vitest-runner";
const code = await run({
testDir: "src/tests"
});
process.exit(code);
选项
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
cwd | string | process.cwd() | 绝对工程根目录 |
testDir | string | cwd | 目录(绝对或相对 cwd扫描 *.test.vitest.{js,mjs,cjs} 文件 |
vitestConfig | string | 自动检测 | 清晰的vitest 配置路径; 当省略了行走标准配置名称时(vitest.config.ts, (中文(简体) ), vite.config.ts(a) 与 cwd |
testPatterns | string[] | [] | 要过滤的文件/ 文件夹模式—— 空代表所有文件 testDir |
testListFile | string | undefined | JSON 数组测试文件路径的路径; 设定时, 扫描被全部跳过 |
testFilePattern | RegExp | DEFAULT_TEST_FILE_PATTERN | 发现时与文件名相匹配的Regex(*.test.vitest.{js,mjs,cjs} (默认) |
exclude | string[] | [] | 目录 / 文件 globs, 相对 cwd,该发现从未进入(例如:. ['tmp/**']) (中文(简体) ). 适用于默认扫描和部分路径模式分辨率 |
vitestArgs | string[] | [] | 额外 CLI 参数逐字传送到每个 vitest 引用 |
showErrorDetails | boolean | true | 在摘要中每个失败的文件下打印内行错误块 |
coverageQuiet | boolean | false | 禁止每个文件输出; 只显示进度栏和最后摘要 |
suppressFileOutput | boolean | false | 在所有模式中禁用每个文件跑者输出块 |
suppressPassingFiles | boolean | false | 在最后摘要中隐藏通过的文件行 |
topSummary | boolean | true | 显示或隐藏顶部内存/ 期限摘要部分( 以及 JSON 阵列) |
json | boolean | false | 返回 JSON 报告对象而不是打印文本输出 |
workers | number | 4 | 最大平行工人档次(覆盖) VITEST_WORKERS(中文(简体) ) |
worstCoverageCount | number | 10 | 覆盖后最差的覆盖表行数(0 关闭它) |
blobsDir | string | <cwd>/.vitest-coverage-blobs | 每个文件覆盖blobs的目录 。 相对路径解析 cwd。总是在覆盖运行开始时清除 |
mergeReports | boolean | true | 何时 true,blobs通过 vitest --mergeReports,并印刷报道摘要 blobsDir 删除。 何时 false,在产生blobs后运行停止——没有合并,没有摘要——和 blobsDir 被保存为外部合并 |
maxOldSpaceMb | number | undefined | 全球 --max-old-space-size 甲基溴上限(覆盖) VITEST_HEAP_MB(中文(简体) ) |
earlyRunPatterns | string[] | [] | 路径子字符串 — 匹配文件在平行工人池启动前单独运行( 一次一个) |
perFileHeapOverrides | PerFileHeapOverride[] | [] | 每个文件的最小堆积上限;最大此和 maxOldSpaceMb 赢 |
conditions | string[] | [] | 额外 --conditions 转发给儿童的节点旗帜 |
nodeEnv | string | 'development' | 写入的值 NODE_ENV 在儿童过程中 |
scratchDir | string | 'tmp/vitest-runner' | 每个运行的抓取根,相对于 cwd (或为绝对. 每个文件引用创建一个子目录,并通过 VITEST_RUNNER_TMP |
keepTmp | boolean | false | 保留运行的抓取根,而不是在完成时删除(正常退出,失败,或SIGINT/SIGTERM) |
fsModuleCachePath | string | false | <cwd>/node_modules/.vitest-cache | 测试 5+ fsModuleCache 每个孩子的目录,相对于 cwd (或为绝对. 覆盖 Vitest 配置中的路径; a --fsModuleCachePath 转接电源会超过这个 当未设定时,默认仅在解析的配置(root 或任何工程)没有设置路径时适用. false 没有增加什么。 见 Vitest 模块缓存 |
PerFileHeapOverride
{
pattern: string;
heapMb: number;
}
pattern 是和正态文件路径相匹配的子字符串。 首场比赛获胜 与全局相比 maxOldSpaceMb;使用了更大的值.
实例
// Run all tests under src/tests/ (cwd defaults to process.cwd())
await run({ testDir: "src/tests" });
// Run only the config and metadata suites
await run({
testDir: "src/tests",
testPatterns: ["src/tests/config", "src/tests/metadata"]
});
// Coverage run (OOM-safe blob + merge mode)
await run({
testDir: "src/tests",
vitestArgs: ["--coverage"]
});
// Quiet coverage with live progress bar
await run({
testDir: "src/tests",
coverageQuiet: true
});
// Machine-readable output (no text logs)
const report = await run({
testDir: "src/tests",
json: true
});
console.log(report.exitCode);
// Give heap-heavy files a larger ceiling while keeping the global limit lower
await run({
testDir: "src/tests",
maxOldSpaceMb: 2048,
earlyRunPatterns: ["listener-cleanup/"],
perFileHeapOverrides: [{ pattern: "listener-cleanup/", heapMb: 6144 }]
});
剪切目录( S)VITEST_RUNNER_TMP 编号 : makeRunTmpDir(中文(简体) )
每个跑步都有自己的抓取根(<scratchDir>/<pid>-<timestamp>/),在任何文件运行之前创建,一旦运行完成即被删除——成功、失败和SIGINT/SIGTERM——除非 keepTmp 已经设定。 每一个引用文件都会在根下获得自己的子目录,被孩子暴露为 process.env.VITEST_RUNNER_TMP。在下一次运行开始时会扫描被崩溃的前一运行(已死 PID)所留下的 Stale 根 .
从测试文件中, 使用 makeRunTmpDir(label) 以获得一个新的,唯一命名的子目录,而不是管理自己的 mkdtemp 基础 :
import { makeRunTmpDir } from "@cldmv/vitest-runner";
const dir = makeRunTmpDir("my-fixture"); // a fresh directory under VITEST_RUNNER_TMP
CLI 旗帜 : --scratch-dir <path> 财务报告和审定财务报表 --keep-tmp (见 运行中旗 (见上文).
Vitest 模块缓存
磁盘上的 Vitest 5 缓存转换模块(fsModuleCache,默认为5.0.5). 它的默认位置是 node_modules/.vitest-cache 地点 工作空间根,由工作空间中的每个软件包共享,当锁文件与缓存所要保存的文件不同时,每个vitest进程会在启动时删除整个目录. 锁文件更改后立即开始的几个进程都试图删除, 有些进程失败了 ENOTEMPTY。在一个工作空间中拥有自己的锁文件的软件包也不断相互清除对方的缓存.
在任何文件运行前,跑者会启动一个简短的助手进程,按照工人的方式加载工程的Vitest配置(根和每个工程),以及:
- 每个软件包选择缓存:当缓存打开而没有任何东西设置路径时,每个孩子都会得到
--fsModuleCachePath=<cwd>/node_modules/.vitest-cache,所以一个包的运行 永远不会清除另一个的缓存; - 检查过锁文件一次:它从Vitest开始一次用工人的rg来取出,它清除了一个 stale 缓存,然后退出. 然后工人们开始一个与锁文件匹配的缓存. 当独奏文件先运行(第一个独奏文件做同样的工作),文件从不平行运行,或缓存关闭时,此步骤被跳过.
缓存路径按此顺序选择 :
- (单位:千美元)
--fsModuleCachePath(一) 转接; - 页:1
fsModuleCachePath选项(false不增加任何内容,而留下维特自己的设定; fsModuleCachePath设置在已解析的配置中的任何位置,包括项目本身的配置;<cwd>/node_modules/.vitest-cache。 。 。 .
这不适用于5前的Vitest,如果帮助者失败或耗时超过一分一分,则没有它,跑道就会继续. 关闭缓存,通过 --fsModuleCache=false 或设置 fsModuleCache: false 在 vitest 配置中.
QQ 覆盖模式
何时 --coverage (或 coverageQuiet: true)通过,跑者使用blob-per-file策略:
- 每个文件都收到
--coverage --reporter=blob带有自己的临时输出目录. - 完成所有文件后,
vitest --mergeReports将 blobs 合并为一个报告 . - 临时blob和覆盖-tmp目录自动清理.
这样可以避免当一个单一的vitest进程同时持有上千个文件的覆盖数据时发生的OOM崩溃.
覆盖静态模式
--coverage-quiet 编号 : coverageQuiet: true 压制每个文件的所有输出, 并让一个实时进度栏代替 。 完成后会打印覆盖表和任何故障。 在此模式下运行时,输出也被反射到 coverage/coverage-run.log (只有CLI) 带有 ANSI 颜色代码剥离,所以文件可以在任何编辑器中被人读取.
日志文件路径可被覆盖 --log-file <path>。通过 --log-file 本身只允许日志镜像(它不允许覆盖模式).
没有测量文件时
如果覆盖 include 匹配任何文件( 例如, 脚手架的回放带有测试但还没有来源), istanbul 报告每个百分比为 Unknown 而不是一个数字。 跑步者将那些指标打印为 Unknown —— 说 Coverage Unknown% lines | Unknown% statements | … - 增加一个说明,即没有计量文件,也没有出口 0 如果测试通过。 这同样适用于最坏的覆盖表中的任何个人非数字百分比.
覆盖阈值在此情况下被跳过, 因为没有什么可以衡量的: vitest 本身的阈值检查不会失败 Unknown 百分比,而跑道者不添加自己的支票。 阈值一旦至少一个文件被测量,就再次适用. JSON的报告 coverageSummary.noFilesMeasured 实值 true 为这样的跑.
为外部合并生成 blobs
设定 mergeReports: false (CLI): (中文(简体) ) --no-merge-reports)在每个文件的blobs被写入后停止运行. 内部 vitest --mergeReports 呼叫和报道摘要被省略 blobsDir ,而不是删除。 Blobs 目录仍在清理 开始 因此它只包含当前运行的输出.
当第二个覆盖blobset(例如,浏览器-模式运行的覆盖变换不同)需要与节点-模式blobs合并时,这样做是有用的. 在已知目录中标出两者 blobsDir,然后将它们合并为一个外部 vitest --mergeReports 步骤 :
// Node-mode blobs, no internal merge
await run({
testDir: "src/tests",
vitestArgs: ["--coverage"],
blobsDir: ".coverage-blobs/node",
mergeReports: false
});
// (separately produce browser-mode blobs into .coverage-blobs/browser)
// then merge both blob sets in a single external step:
// vitest --mergeReports .coverage-blobs --coverage
退出代码仍然反映测试通过/失败;只是没有覆盖-并发结果可以折叠.
QQ 测试列表文件
一个测试列表文件是一个简单的 JSON 阵列的测试文件路径(与 cwd:
["src/tests/auth/login.test.vitest.mjs", "src/tests/auth/register.test.vitest.mjs", "src/tests/config/defaults.test.vitest.mjs"]
过 --test-list <file> (CLI)或 (中文(简体) ) testListFile: 'path/to/list.json' (API) 运行这些文件而不是扫描 testDir。 。 。 .
QQ 测试文件命名
默认情况下, 运行者会发现匹配的文件 :
*.test.vitest.js
*.test.vitest.mjs
*.test.vitest.cjs
文件在 node_modules 或隐藏目录(名称起自 .总是跳过.
模式可以用 --file-pattern <regex> (CLI)或 testFilePattern 选项( API ):
# Match .spec.ts files instead
vitest-runner --file-pattern '\.spec\.ts$'
await run({ cwd, testDir: "src", testFilePattern: /\.spec\.ts$/i });
QQ 源版式
dist/ ← built library entry (npm run build / tsup) — generated, not committed
index.mjs ← bundled ESM entry
index.cjs ← thin CJS entry, copied verbatim from src/index.cjs; require()s index.mjs
bin/ ← built CLI binary (npm run build / tsup) — generated, not committed
vitest-runner.mjs ← bundled CLI, from src/bin/vitest-runner.mjs (shebang preserved)
src/
index.mjs ← main run() API + re-exports
index.cjs ← CommonJS entry source (copied to dist/index.cjs by the build)
bin/
vitest-runner.mjs ← CLI entry SOURCE — run this directly for source-level dev/testing
utils/
ansi.mjs ← stripAnsi, colourPct
duration.mjs ← formatDuration
env.mjs ← buildNodeOptions, buildEnv
resolve.mjs ← resolveBin, resolveVitestConfig
core/
discover.mjs ← discoverVitestFiles, sortWithPriority, computeFilterConflicts
parse.mjs ← parseVitestOutput, deduplicateErrors
spawn.mjs ← runSingleFile, runVitestDirect, runMergeReports
report.mjs ← printCoverageSummary, printMergeOutput
progress.mjs ← createCoverageProgressTracker
scratch.mjs ← makeRunTmpDir + the scratch-directory lifecycle
fs-cache.mjs ← prepareFsModuleCache: Vitest module cache path + one-time lockfile check
fs-cache-helper.mjs ← helper process started by fs-cache.mjs (built to dist/ and bin/)
cli/
args.mjs ← parseArguments
help.mjs ← showHelp
src/ 未出版——仅 dist/, (中文(简体) ), bin/,以及 types/ 船舶(见 程序化 API 联 合 国 vitest-runner-dev 导出条件,用于对照工作空间/本地取出而不是已发布的软件包开发时。 所有子模块的公用设施都从根入站再出口,因此深入是可选的.
页:1
- 更改日志 ——每个版本发布注释
- GitHub 上的发布注释 – 每个放行标记所附带的同同名注释
捐款
欢迎错误报告和调取请求 GitHub 图像。拉请求目标 next 分支; 释放船舶 next 改为 master。 。 。 .
链接
- 无数字 : @cldmv/最差跑者
- GitHub 图像数字 : 机动车辆/特别跑车
- 问题数字 : GitHub 问题
- 更改日志数字 : 文件/更改日志/
- 释放数字 : GitHub 发布
许可证
阿帕奇-2.0 ©正来/ CLDMV. 见 自由主义 全文.