- 桌面应用
【免费下载链接】Vortex
Vortex Development
本篇指南以 CONTRIBUTING.md 为骨架,系统讲解如何为 Vortex 提交代码:包括当前维护团队对 PR 规模的硬性约束与 AI 辅助贡献要求、从零搭建开发环境的分步流程、pnpm run verify/build/start/dev等核心命令的底层实现、热重载与 VS Code 调试技巧,以及本地打包与分支发布策略。读完你将掌握一套可直接上手的 Vortex 贡献实战流程,并理解其背后基于 pnpm + Nx + Electron 的工程化设计。
一、先说结论:当前只接受小 PR
在动手写任何代码之前,请先读完 CONTRIBUTING.md 开头那条醒目的[!IMPORTANT]提示:当前阶段只接受小规模 Pull Request。原因很直接——Vortex 正经历大规模的基础架构重构(large foundational changes),维护团队没有足够的评审产能同时处理大贡献与重构工作。如果你现在提交一个大 PR,它大概率会一直处于未评审状态,直到与底层代码脱节而被迫关闭。
这条规则针对的是团队的评审产能,而不是你贡献的质量。文档也明确表示团队正在招聘、状况会变化。
什么算“小”?
文档给出了一个粗略的量化标准:改动不超过 400 行、涉及文件不超过 10 个(忽略 lockfile、生成文件与大规模重命名)的 PR,可以不经过前期沟通直接评审。
但这并非硬性上限,判断标准其实是影响半径(blast radius)而非行数:
- 一个 500 行的改动,如果是一个自包含的修复并配有测试,可以接受;
- 一个 200 行的改动如果牵动六个扩展,大概率不行——因为评审成本在于它波及多少子系统,而不在于行数本身。
如果你的改动超出上述规模、或跨越多个扩展,文档强烈建议:先写 feature request,或在 Discord 上先与维护者沟通方案,并等待对方认可后再动手。开写之前花几分钟对话,能避免你投入大量时间写出一份无法合并的东西。
二、Pull Request 提交规范
CONTRIBUTING.md 对 PR 本身提出了三条硬性要求:
- 一个 PR 只做一件逻辑上的事。如果 PR 描述里需要出现 "and" 这个词,那它大概率应该拆成两个 PR。
- 关联它修复的 issue(Link the issue it fixes)。
- 说明你测试了什么、在哪个平台上测试的(Say what you tested and on which platform)。
- 开 PR 之前必须运行
pnpm run verify。这一步覆盖格式检查(formatting)、lint、类型检查(typecheck)、构建(build)与测试(test)。
值得注意的是,与既有已规划/进行中的工作冲突、不符合架构、或大到团队无法评审的 PR,会被直接关闭——文档强调“这不是对代码质量的评判”。
verify 命令到底做了什么?
查看仓库根目录的 package.json,verify的实际定义是一条命令链:
pnpm run format && pnpm run build && pnpm run test其中:
format→pnpm oxfmt(格式统一交给 oxfmt,包括 Markdown 在内);build→pnpm nx run-many -t build lint typecheck && pnpm run assets(Nx 并行跑所有子项目的 build/lint/typecheck,再生成依赖报告资产);test→pnpm nx run-many -t test test:integration --exclude @vortex/e2e(注意:verify 刻意排除了 E2E 套件,因为@vortex/e2e需要打包好的应用和真实游戏安装,见 AGENTS.md 的 Verification 一节)。
另外,AGENTS.md 还给出了一个容易被忽略的警告:不要在 dev 会话(pnpm run dev或 VS Code "Debug Electron" 运行中)期间运行verify。因为 verify 的 build 步骤会把生产产物写入src/main/build——这正是运行中的应用加载的目录,会覆盖tailwind:watch生成的 CSS 并替换 HMR 渲染器 bundle,导致样式损坏、HMR 失效,直到重启 dev。dev 会话期间请改用不写该目录的检查:pnpm run typecheck、pnpm run lint,以及从所属项目目录内执行pnpm exec vitest run <file>跑单个测试。
三、AI 辅助贡献:工具随意,责任在你
Vortex 对 AI 生成的代码持开放但严格的态度:你可以使用任何工具,但必须满足同一个要求——你是作者,你必须理解你提交的每一行代码。
落实到实践中,这意味着你需要能够解释为什么改动这样写、已经实际运行过它、并且通读了 diff。如果评审者就 PR 中的某个决策提问,回答"这是模型生成的"(that's what the model produced)不算答案。
团队会直接关闭大规模机器生成的 PR 而不做详细评审——没有人有产能去审计两边都没读过的成千上万行代码,前述规模规则与代码由谁生成无关。因此在使用 AI 辅助时,务必把改动控制在"小 PR"范围内,并逐行理解后再提交。
文档推荐的编辑器是 VS Code,首次打开仓库时会提示安装工作区扩展。
四、环境要求与 Setup:从零开始搭建开发环境
开始之前,请确认具备以下基础条件:
- 用于创建 PR 的GitHub 账号;
- gitCLI 或 Git GUI 客户端(如 GitHub Desktop);
- 支持 TypeScript 的编辑器:VS Code、WebStorm 或 Neovim。
仓库采用pnpm workspace + Nx的 monorepo 结构(见 pnpm-workspace.yaml),根级 package.json 声明packageManager: pnpm@11.10.0,engines/devEngines固定 Node.js 24.20.0。pnpm 是唯一需要手动安装的工具——仓库会在安装时自动切换到它锁定的 pnpm 版本,并下载固定的 Node.js 运行时,无需版本管理器。
4.1 按发行版安装前置依赖
CONTRIBUTING.md 的 Setup 一节按平台拆分了前置依赖文档,需要先安装系统级依赖,再进入共享安装流程:
| 平台 | 依赖要点 | 对应文档 |
|---|---|---|
| Windows | VS 2022 Build Tools(含 C++ 桌面开发工作负载、MSVC v143、ATL/MFC、Windows 11 SDK)、Git、Python 3.14+、CMake、.NET 9 SDK | docs/install-instructions/windows.md |
| Arch / CachyOS / Manjaro | base-devel git python python-setuptools dotnet-sdk-9.0 | docs/install-instructions/archlinux.md |
| Debian / Ubuntu / Pop!_OS / Linux Mint | build-essential git python3 python3-setuptools curl wget libfontconfig-dev+ .NET 9 SDK | docs/install-instructions/debian-based.md |
| Fedora | development-tools组包 +git python3 python3-setuptools dotnet-sdk-9.0 gcc g++ fontconfig-devel | docs/install-instructions/fedora.md |
| NixOS | 用 flake 提供全部依赖(含 pnpm/node),替代手动安装 pnpm | docs/install-instructions/nixos.md |
| 其他发行版 | .NET 9 SDK + Python 3.12+(需 setuptools)+ C/C++ 工具链 | docs/install-instructions/generic.md |
几个值得注意的细节(均来自对应安装文档):
- Windows上官方推荐把仓库克隆到
C:\v,以规避 Windows 路径长度限制;Vortex 依赖原生 Node 模块,node-gyp编译需要 ATL、MFC 与 Windows 11 SDK,所以"Desktop development with C++"默认工作负载不够用,必须按文档补选 Individual Components。 - NixOS用户不需要手动安装 pnpm,
direnv allow之后由仓库 dev shell 提供;但要注意:在仓库外启动 Git GUI 客户端(如 GitKraken)时,pre-commit 钩子可能因找不到pnpm而失败。 - Generic指南特别强调 Python 3.12+ 需要额外安装
setuptools。
4.2 共享安装流程(Shared Setup)
完成发行版前置依赖后,进入 docs/install-instructions/shared.md 描述的共享流程:
Linux:
git clone --recurse-submodules https://github.com/Nexus-Mods/Vortex.git cd Vortex curl -fsSL https://get.pnpm.io/install.sh | sh - # 安装 pnpm pnpm install # 安装依赖Windows(PowerShell):
git clone --recurse-submodules https://github.com/Nexus-Mods/Vortex.git C:\v cd C:\v winget install -e --id pnpm.pnpm pnpm install关于pnpm install的机制,shared.md 解释得很清楚:步骤 2 安装的 pnpm 只负责"引导"流程,真正安装时 pnpm 会读取package.json里的packageManager字段自动切换到精确版本,再按devEngines.runtime下载锁定的 Node.js——编译原生模块是这一步最耗时的部分。
pnpm install还会自动安装 git pre-commit 钩子(用于自动格式化)。如果钩子缺失,可手动执行:
pnpm run prepare(根级prepare: husky,hook 配置见 package.json 的lint-staged:对每个暂存文件运行pnpm exec oxfmt。)
安装完成后可用以下命令验证环境(来自 shared.md 的 Verify Setup):
git --version pnpm --version pnpm exec node --version # 报告仓库锁定的 node 版本,未必等于 PATH 上的版本 pnpm nx --version python3 --version dotnet --list-sdks五、Developing:构建与启动
Setup 完成后,日常开发循环就两行命令:
pnpm run build # 全量构建 pnpm run start # 启动 Electron 应用- 根级
build通过 Nx 并行执行所有子项目的build lint typecheck,随后运行assets脚本生成依赖报告(见 package.json); start实际是pnpm nx run @vortex/main:start,而@vortex/main的 start 目标是pnpm electron .(src/main/package.json),即从主进程构建产物build/main.cjs启动 Electron。
关于格式化,务必有心理准备:pre-commit 钩子会对每个暂存文件(含 Markdown)重写oxfmt格式,所以你会看到自己的格式被改写。想避免这种"惊扰",先手动跑一遍pnpm run format,钩子就变成 no-op 了。另外钩子可能在提交中途触发依赖安装,因此一次 commit 有时会耗时约 30 秒并打印安装输出,这是正常现象。
六、Hot Reload:用pnpm run dev迭代 UI
针对渲染进程(renderer / UI)代码的迭代,pnpm run dev可以完全绕开 build/start 的循环——它启动 webpack 与 Tailwind 的 watch 模式,并以热模块替换(HMR)方式启动 Electron(见 CONTRIBUTING.md 的 "Hot reload" 一节)。
dev的实际组成可以从 nx 配置还原出来:根级dev→pnpm nx run @vortex/main:dev,而@vortex/main的dev目标(continuous、cache 关闭)依赖两条 watch 流水线:
@vortex/stylesheets的tailwind:watch(Tailwind CSS 增量编译);@vortex/renderer的watch,其 executor 为pnpm -F @vortex/renderer exec node ./dev.mjs(见 src/renderer/package.json)。
renderer 的 dev.mjs 源码揭示了底层机制:它以WEBPACK_WATCH: true调用 webpack watch,首次编译成功后才 spawnpnpm -F @vortex/main run start启动 Electron,并在每次编译结束时打印[vortex-hmr] finished after <N>ms: <hash>;同时会清理src/main/build下残留的*.hot-update.*文件。
各类型改动的热更新行为
| 改动类型 | 行为 |
|---|---|
组件(.tsx) | 通过 react-refresh 原地热替换,React 与 Redux 状态保留,无需重载 |
无法热应用的改动(reducers、utils、扩展index.ts初始化代码) | 自动触发一次干净的窗口重载 |
| Tailwind class 变更 | 重建tailwind-v4.css并原地换样式表,无需重载 |
主进程(src/main)、preload、@vortex/shared | 不受 HMR 覆盖,需要重启pnpm run dev |
extensions/与extensions/games/下的动态扩展 | 不受 HMR 覆盖,需要重新启动应用 |
主进程侧的佐证也在源码里:MainWindow.ts的will-navigate处理器对"当前页面的导航"(即 HMR 回退触发的页面刷新,见 MainWindow.ts 中引用的tools/hmr-client.cjs)做了放行判断,说明 HMR 的回退重载走的是页面级 reload。
七、Debugging:VS Code 调试
CONTRIBUTING.md 给出的调试要点非常简洁:
- F5同时调试主进程与渲染进程;
- 调试前先
pnpm run build(保证 source map 是最新的)。
详细的调试手册在 docs/DEBUGGING-GUIDE.md,这里提炼几个与贡献流程直接相关的关键点:
7.1 调试配置(.vscode/launch.json)
默认的Debug Electronprofile 是一个 compound,同时启动:
- Debug Main Process:以
NODE_ENV=development、START_DEVTOOLS=true、--remote-debugging-port=9222启动 Electron; - Debug Renderer Process:attach 到 9222 端口上的渲染进程。
其余可用 profile 包括 Debug Main Process(单独调试主进程,适合启动流程、IPC、文件系统、更新器)、Debug Renderer Process(先启动主进程再 attach)、Debug Jest Tests,以及为 NixOS 等需要系统 Electron 的环境准备的 "System Electron" 系列和用于测试发布更新的 Staging 系列(设置VORTEX_DEV_UPDATER=1与VORTEX_UPDATER_REPO)。
7.2 断点与常见坑
- 主进程断点建议下在 src/main/src/main.ts 及
src/main/src/*.ts;渲染进程断点下在 src/renderer/src/renderer.tsx、src/renderer/src/views/*.tsx、src/renderer/src/extensions/**/*.ts。 - 热替换过的代码会让基于行的断点失效,直到下一次完整重载——如果断点不触发了,按 Ctrl+R 重载窗口。
- 断点打不中的通用排查顺序:重建
pnpm run build→ 确认src/main/build/下有最新产物 → 核对 launch.json 的outFiles与构建输出匹配 → 重启 VS Code 清断点缓存。
7.3 诊断环境变量
DEBUGGING-GUIDE.md 汇总了一批在.env或启动 shell 中设置即可生效的诊断开关,常用的有:
| 变量 | 作用 |
|---|---|
START_DEVTOOLS=true | 启动时自动打开 DevTools(MainWindow.ts中由isEnvSet("START_DEVTOOLS")触发,见 MainWindow.ts) |
VORTEX_ENABLE_LOGGING=1 | 在非NODE_ENV=development构建中打开文件日志 |
DEBUG_REACT_RENDERS=true | 阻止窗口 focus/blur 更新状态,避免检查渲染时引入干扰 |
HIGHLIGHT_I18N=true | 把所有翻译字符串大写并加TT:前缀,让硬编码字符串一目了然 |
VORTEX_DEV_UPDATER=1+VORTEX_UPDATER_REPO | 从源码运行更新器并指定它读取的仓库 |
VORTEX_TRACE_DB_WRITES=1 | 为LevelPersist每次写入输出面包屑日志,用于定位持久化队列挂起问题 |
日志文件位置也有区分:开发构建(从源码运行)写%appdata%/@vortex/main/*.log,生产构建写%appdata%/vortex/*.log,日志级别为[DEBG]/[INFO]/[WARN]/[ERRO]。排查"退出时无限挂起"这类问题,VORTEX_TRACE_DB_WRITES=1是关键工具——最后一次没有对应exit的enter行就是卡住的那次调用(相关阈值SLOW_WRITE_THRESHOLD_MS定义于 src/main/src/store/LevelPersist.ts)。
八、Packaging:本地打包与发布管线
8.1 本地构建未签名 Windows 安装包
想要在本地验证生产行为(如自动更新流程),从仓库根目录运行:
pnpm package:nosign产物输出到根目录的dist/。签名安装包只由 CI 产出,本地不要运行pnpm package(签名变体)。
根级定义(package.json)显示两者都会先以NODE_ENV=production跑完整 build,再调用@vortex/main的package:nosign。而 src/main/package.json 里的 pipeline 链条是:publish(清空dist、pnpm deploy物化独立包、prepare-dist-package.mjs解析catalog:/workspace:依赖)→ electron-builder 从部署目录运行并输出到仓库根dist/。
几个来自 docs/packaging/windows.md 的实操要点:
- 安装包内置的版本号来自
src/main/package.json的占位符1.0.0,打指定版本需先注入再还原:
pnpm -F "@vortex/main" version 2.7.0 --no-git-tag-version --no-git-checks --allow-same-version pnpm package:nosign git restore src/main/package.json- 陷阱:
src/main内的package/package:nosign脚本单独运行会失败(找不到部署目录),它们依赖根级管线创建的 deploy 目录,所以永远使用根级脚本。 - 打包后建议运行 asar 校验脚本,它会对比部署树中每个嵌套
node_modules依赖版本与 asar 内实际版本,不一致即报错:
node scripts/verify-packaged-asar.mjs- 产物包括
vortex-setup-<version>.exe(NSIS 安装器)、.exe.blockmap(差分自动更新)、latest.yml(更新器清单)与win-unpacked/(免安装目录)。 - 构建安装包的版本注入用
pnpm -F "@vortex/main" version ...,注意该命令使用--no-git-tag-version等参数避免误提交。
8.2 Flatpak 打包(Linux)
Flatpak 打包流程在 docs/packaging/flatpak.md,注意文档顶部有[!WARNING]:当前 Flatpak 构建暂时是坏的(pnpm 支持待修复),所以这条路径仅供了解。
常用工作流(脚本位于flatpak/scripts/,会自动安装flatpak-node-generator依赖并补充 Flathub remote):
# 快速开发测试:构建 + 运行 python3 flatpak/scripts/flatpak_build.py python3 flatpak/scripts/flatpak_run.py # 安装到本地仓库(可出现在 KDE Discover / GNOME Software 中) python3 flatpak/scripts/flatpak_install.py python3 flatpak/scripts/flatpak_install.py --skip-build # 已构建过则跳过 # 生成 .flatpak 分发 bundle python3 flatpak/scripts/flatpak_bundle.py python3 flatpak/scripts/flatpak_bundle.py --skip-build首次构建前需初始化子模块:git submodule update --init --recursive。
九、FAQ:我的改动何时进入 stable 版本?
CONTRIBUTING.md 的 FAQ 指向 docs/branching-and-release-strategy.md,核心策略如下:
- master 永远是最新代码,是所有新工作的起点;
- 版本准备稳定时从 master 切出同名分支(如
v2.0),该版本的 alpha/beta/stable 全部在此分支进行; - Bug 修复的流向:同时影响 release 分支与 master 的 bug,先在更相关的分支修,再 cherry-pick 到另一边;只影响单一分支的 bug 就地修复;不确定时与团队确认;
- 停止 backport 的时机:版本进入 stable、下一版本分支已切出后,旧 release 分支进入维护模式,此后只 backport 关键修复(崩溃、数据丢失、安全);
- 标签与命名:分支用版本名(
v2.0),标签遵循 semver(v2.0.0-alpha.1、v2.0.0-beta.1、v2.0.0,补丁版本v2.0.1);稳定版热修复直接在 release 分支上修复并打补丁标签,不要创建单独的热修复分支。
十、Further Reading:继续深入仓库
CONTRIBUTING.md 推荐了三个进一步阅读入口,均已转换为仓库根目录相对路径:
- 所有文档索引——按主题组织的完整文档目录,Vortex 的"Start here"建议先读 docs/repo-layout.md(仓库布局与"改某类东西从哪里开始"的对照表)与 docs/writing-documentation.md;
- 调试指南——VS Code 调试、日志文件、DevTools、Redux DevTools、性能排查;
- Docker Dev Containers——docker/linux/Dockerfile.devcontainer 基于 Ubuntu 24.04,内置 git、python3、.NET SDK 9.0(fomod-installer 所需)、Volta 等全部构建依赖,可用于 VS Code Dev Containers 或 GitHub Codespaces。
另外,仓库根目录的 CODESTYLE.md 对代码风格提出了具体要求,贡献前值得浏览:例如行宽软限制 100 字符/硬限制 150、函数软限制 25 行、接口命名用I前缀、私有字段优先用#而非 TSprivate、错误信息中动态部分必须用引号包裹(因为错误上报按消息与堆栈分组去重)等。
总结:一份可执行的最小贡献清单
综合全文,一次符合规范的 Vortex 贡献可以归纳为六步:
- 控制规模:改动 ≤400 行、≤10 文件,单个逻辑变更,超出范围先与维护者沟通方案;
- 搭建环境:按发行版安装前置依赖(Windows 见 windows.md,Linux 见对应发行版文档),再执行共享流程(shared.md);
- 本地开发:
pnpm run build+pnpm run start起步;迭代 UI 用pnpm run dev享受热重载; - 验证:开 PR 前运行
pnpm run verify(覆盖 format/lint/typecheck/build/test,且不含 E2E);dev 会话期间改用 typecheck/lint/单测; - 调试与打包:VS Code 按 F5 双进程调试,需要生产行为验证时用
pnpm package:nosign; - 提交:描述里写明修复的 issue 与测试平台,接受 pre-commit 钩子对格式的重写,等待评审。
若使用 AI 辅助生成代码,请牢记文档的底线:你必须理解提交的每一行,并能解释任何评审问题——这与"工具随意"并不矛盾,责任始终在作者这一侧。
- 桌面应用
【免费下载链接】Vortex
Vortex Development
相关推荐
Popcorn Time开发者贡献指南:Git工作流与PR规范
Popcorn Time开发者贡献指南:Git工作流与PR规范 作为开源项目Popcorn Time的贡献者,遵循规范的Git工作流和Pull Request(
音视频Hypothesis 开发者贡献指南:从测试编写到 PR 合并的完整工作流
Hypothesis 开发者贡献指南:从测试编写到 PR 合并的完整工作流 本文是 Hypothesis(Python 属性测试库)仓库内开发者工作流指南的深度
测试开发工具Langflow 贡献指南:从 PR 规范到组件、Bundle 与模板的完整开发工作流
Langflow 贡献指南:从 PR 规范到组件、Bundle 与模板的完整开发工作流 Langflow 是一个用于构建和部署 AI Agent 与工作流的开源
人工智能大模型AI AgentRAG后端前端MCP 服务工作流自动化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考