tech-interview-handbook 的 Vite+ 工具链实战:vp 命令工作流、统一配置与 Agent 协作约定
本文基于仓库根目录的 AGENTS.md,系统讲解 tech-interview-handbook 这个 monorepo 所使用的 Vite+ 统一前端工具链:包括 vp 全局 CLI 的完整命令工作流、它如何封装 pnpm 与 Vite/Vitest/Oxlint 等底层工具,以及配合 vite.config.ts、CI 工作流和 git 钩子形成的自动化验证体系。读完你可以直接照做:用 vp 完成安装、开发、测试、构建全流程,并理解仓库中"为什么不能直接调用 pnpm/npx/vitest"的设计约定。
什么是 Vite+:一套统一封装的 Web 工具链
根据 AGENTS.md 的定义,本项目使用的是 Vite+——构建在 Vite、Rolldown、Vitest、tsdown、Oxlint、Oxfmt 和 Vite Task 之上的统一工具链。它的核心特征是:
- 单一全局 CLI:Vite+ 把运行时管理(Node.js 版本)、包管理(pnpm/npm/Yarn)和前端工具链封装进一个名为
vp的全局二进制; - 与 Vite 的区别:Vite+ 独立于 Vite,但它通过
vp dev和vp build来调用 Vite 自身; - 版本可查:所有被封装工具的实际版本都可以用
vp --version查看,这在排查文档、特性与 bug 时非常有用,因为你查的是vp实际携带的工具版本,而不是node_modules里可能并不存在的包。
在 tech-interview-handbook 仓库中,Vite+ 的依赖来源定义在 pnpm-workspace.yaml:
catalog:
vite: npm:@voidzero-dev/vite-plus-core@latest
vitest: npm:@voidzero-dev/vite-plus-test@latest
vite-plus: latest
overrides:
vite: 'catalog:'
vitest: 'catalog:'
也就是说,工作区中任何包声明的 vite 和 vitest 依赖都会被重定向到 Vite+ 官方分发的包(@voidzero-dev/vite-plus-core / @voidzero-dev/vite-plus-test),这从依赖层面保证了"底层工具只经由 Vite+ 使用"这一约束。根目录 package.json 同样只声明了 "vite-plus": "catalog:" 这一个 devDependency,并锁定了运行环境:
"engines": {
"node": "25.8.1",
"pnpm": "10.32.1"
},
"packageManager": "pnpm@10.32.1"
这正是 AGENTS.md 所说"自动检测并封装底层包管理器"的落地方式:vp 通过 packageManager 字段和 lockfile 识别出本项目使用 pnpm,之后所有依赖操作都应经由 vp 转发,而不是直接敲 pnpm。
vp 命令工作流总览
vp 覆盖完整开发生命周期。查看命令列表用 vp help,查看某个命令的细节用 vp <command> --help。AGENTS.md 将命令按生命周期分为六组:
Start(启动阶段)
| 命令 | 作用 |
|---|---|
create |
从模板创建新项目 |
migrate |
将现有项目迁移到 Vite+ |
config |
配置 hooks 与 agent 集成 |
staged |
对 git 暂存区文件运行 linter |
install(别名 i) |
安装依赖 |
env |
管理 Node.js 版本 |
Develop(开发阶段)
| 命令 | 作用 |
|---|---|
dev |
启动开发服务器 |
check |
一次性运行格式化、lint 与 TypeScript 类型检查 |
lint |
只运行 lint |
fmt |
只运行格式化 |
test |
运行测试 |
Execute(执行阶段)
| 命令 | 作用 |
|---|---|
run |
运行 monorepo 任务(封装 Vite Task) |
exec |
执行本地 node_modules/.bin 中的命令 |
dlx |
不安装依赖即可运行某个包的二进制 |
cache |
管理任务缓存 |
Build(构建阶段)
| 命令 | 作用 |
|---|---|
build |
生产构建 |
pack |
构建库包 |
preview |
预览生产构建产物 |
Manage Dependencies(依赖管理)
| 命令 | 别名 | 作用 |
|---|---|---|
add |
— | 添加依赖 |
remove |
rm / un / uninstall |
移除依赖 |
update |
up |
升级到最新版本 |
dedupe |
— | 去重依赖 |
outdated |
— | 检查过期依赖 |
list |
ls |
列出已安装包 |
why |
explain |
解释某个包为何被安装 |
info |
view / show |
查看 registry 中的包信息 |
link |
ln / unlink |
管理本地包链接 |
pm |
— | 把命令原样转发给底层包管理器 |
Maintain(维护阶段)
| 命令 | 作用 |
|---|---|
upgrade |
将 vp 自身升级到最新版 |
这些命令都一一映射到其背后工具。文档给出了两个典型例子:vp dev --port 3000 直接以 Vite 原生语义运行开发服务器;vp test 通过内置 Vitest 运行 JavaScript 测试。在本仓库中,"运行 monorepo 任务"的 vp run 是出现频率最高的命令——根目录 package.json 的 scripts 全部基于它编排:
"scripts": {
"build": "vp run --cache -r build",
"ci": "vp check && vp test && vp run --cache -r build",
"clean": "vp cache clean",
"dev:portal": "vp run --filter @tih/portal... dev",
"dev": "vp run --filter @tih/website... dev",
"prepare": "vp config"
}
几个值得注意的细节:
vp run --filter @tih/website... dev中的--filter指定任务图里的目标包,...表示沿依赖图传播;本项目有两个应用(Docusaurus 驱动的@tih/website和 Next.js 14 的@tih/portal,见 apps/website/package.json 与 apps/portal/package.json),因此拆出dev与dev:portal两个入口分别启动;--cache让构建走 Vite Task 的缓存(配合vp cache命令管理,vp cache clean即清缓存);prepare: vp config对应 Start 组里的config命令,负责"配置 hooks 和 agent 集成"。从仓库结构看,它的产物包括 AGENTS.md 中被<!--VITE PLUS START-->/<!--VITE PLUS END-->标记包围的整块内容,以及 .vite-hooks/pre-commit 这个 git 钩子(内容即一行vp staged)——可以推断该文件块由vp config生成维护,更新vp时应重新运行此命令而不是手改标记块。
vite.config.ts:fmt、lint、test、staged 的统一配置入口
AGENTS.md 明确要求所有模块从 vite-plus 而非 vite 导入,仓库根目录的 vite.config.ts 正是这一约定的示范:
import { defineConfig } from 'vite-plus';
export default defineConfig({
staged: {
'*': 'vp check --fix',
},
test: {
passWithNoTests: true,
},
// ... fmt / lint 配置
});
各配置块的作用与仓库中的实际行为:
staged:为vp staged命令注册"暂存文件 → 检查动作"的映射。这里'*': 'vp check --fix'表示任何文件类型被 git 暂存后都执行vp check --fix(格式化 + lint + 类型检查并自动修复)。这条配置与 .vite-hooks/pre-commit(内容就是vp staged)配合,构成了提交前的本地防线;test.passWithNoTests: true:允许在没有测试文件的工作区通过vp test。这一点很关键:本仓库的内容主体是 Markdown 面试资料与两个前端应用,并非每个 workspace 都有测试用例,该配置保证了 CI 中vp test步骤不会因"无测试"而失败;fmt:全局格式化策略为bracketSameLine: true、printWidth: 80、singleQuote: true、trailingComma: 'all',并通过overrides为apps/portal/**单独开启 Tailwind 类名排序(引用 apps/portal/tailwind.config.cjs,作用于clsx函数);ignorePatterns则列出了 prisma SQL、二进制图片、.prisma、Docusaurus 产物目录等无需格式化的内容;lint:启用typescript与react插件,将correctness类别整体置为error,并配置了针对 Next.js 的设置(next.rootDir: ['apps/portal/']);规则表覆盖了prefer-const、eqeqeq、no-unused-vars(^_前缀参数豁免)等约 40 条规则,另有一个overrides仅对apps/portal/**追加nextjs插件并放宽nextjs/no-img-element等规则。
编辑器侧与之对齐:.vscode/settings.json 开启了 formatOnSave 以及 source.fixAll.oxc,使 IDE 保存时的行为与 vp fmt / vp lint 保持一致。
常见陷阱:AGENTS.md 明确列出的七条约定
这是 AGENTS.md 中最具操作价值的部分,逐条列全并结合仓库实际展开:
-
不要直接使用包管理器。不要敲
pnpm、npm或Yarn,Vite+ 可以处理所有包管理操作。本仓库虽然声明packageManager: pnpm@10.32.1,但一切依赖操作(安装、添加、更新)都应走vp install、vp add、vp update等;仅当需要透传特殊参数时才用vp pm <command>转发。 -
不要试图用 Vite 命令名去跑底层工具。
vp vitest和vp oxlint这样的命令不存在,应分别使用vp test和vp lint。 -
内置命令优先于同名 package.json 脚本(这是最容易踩坑的一条)。
vp dev、vp build、vp test等永远执行 Vite+ 内置工具,而不会调用package.json里同名的 script。要运行与内置命令同名的自定义脚本,必须用vp run <script>。本仓库就是活例子:@tih/website的dev脚本实际执行docusaurus start(见 apps/website/package.json),它不是 Vite 应用,所以根目录用vp run --filter @tih/website... dev来启动它——如果直接敲vp dev,得到的将是 Vite 开发服务器而不是 Docusaurus。同理@tih/portal的dev脚本是next dev。 -
不要直接安装 Vitest、Oxlint、Oxfmt 或 tsdown。Vite+ 已经封装了它们,直接安装最新版既不能升级这些工具,还会造成版本漂移。一切通过 Vite+ 命令。
-
一次性二进制用
vp dlx,替代各包管理器自己的npx/dlx。 -
从
vite-plus导入模块。不要import from 'vite'或'vitest',正确写法是:import { defineConfig } from 'vite-plus'; import { expect, test, vi } from 'vite-plus/test';不需要(也不应该)为了拿到测试工具而额外安装
vitest。vite.config.ts 首行即遵循此约定。 -
Type-Aware Linting 开箱即用。无需安装
oxlint-tsgolint,vp lint --type-aware直接可用。
Agent 审查清单与自动化验证闭环
AGENTS.md 面向 AI Agent 给出了两条硬性检查项:
- 拉取远端变更之后、开始工作之前,先运行
vp install; - 修改完成后,运行
vp check和vp test验证改动。
这套本地约定与仓库的 CI 完全同构,构成"本地钩子 → 提交 → CI"的三层验证:
- 本地 git 钩子:.vite-hooks/pre-commit 执行
vp staged,对暂存文件按vite.config.ts中staged配置运行vp check --fix; - CI 检查工作流:.github/workflows/lint.yml 在每次指向
main的 PR 上依次执行vp install→vp check→vp test,与根目录ci脚本(vp check && vp test && vp run --cache -r build)的验证段一致; - CI 构建工作流:.github/workflows/tsc.yml(工作流名为 "Build")在同样的环境下执行
vp install,然后分别用vp run --filter @tih/website build和vp run --filter @tih/portal build构建两个应用,并注入了DATABASE_URL、NEXTAUTH_*、SUPABASE_*等环境变量供 portal 的 Next.js/Prisma 构建使用。
两条工作流都通过 voidzero-dev/setup-vp@v1 Action 安装 Vite+,并固定 node-version: '25.8.1' 与 package.json 中 engines.node 保持一致,cache: true 启用依赖缓存。
实操速查:在 tech-interview-handbook 中如何用 vp
结合上文,在本仓库工作时的标准流程是:
vp install # 拉取代码后的第一步(对应 vp i)
vp check # 格式化 + lint + TS 类型检查
vp test # 运行测试(无测试的工作区因 passWithNoTests 通过)
vp run --filter @tih/website... dev # 启动 Docusaurus 文档站(website)
vp run --filter @tih/portal... dev # 启动 Next.js portal
vp run --cache -r build # 带缓存地构建所有 workspace
vp cache clean # 清理任务缓存(对应根目录 clean 脚本)
vp help / vp <command> --help # 命令查询
vp --version # 查看 vp 及各底层工具版本
需要强调的适用前提:以上行为以当前仓库状态为准——Node 25.8.1、pnpm 10.32.1(见 package.json 的 engines 与 packageManager 字段),vite/vitest 由 pnpm-workspace.yaml 统一重定向到 Vite+ 官方包。若你修改依赖或升级工具,请始终通过 vp 提供的命令操作,并保持 AGENTS.md 标记块与 .vite-hooks 钩子通过 vp config(即 prepare 脚本)重新生成,而不是手工编辑。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00