README 写 Rust 1.85+ 而 toolchain 钉的是 1.95:四条版本门槛的两层口径
如果你打算从源码构建 CC Switch,第一件事大概是照着 README 的「环境要求」把工具链装齐。README_ZH.md 的第 447 到 450 行给了四条:Node.js 18+、pnpm 8+、Rust 1.85+、Tauri CLI 2.8+。
问题是,这四条在同一个仓库里各自还有第二个出处——.node-version、package.json 的 packageManager、rust-toolchain.toml、src-tauri/Cargo.toml。逐个比对下来,四条里有三条两层口径对不上,其中 Rust 那一条最反直觉:它在仓库内部就存在两个不同的数,差了十个小版本。
以下全部基于我们本地 clone 的 cc-switch 仓库快照 c39c903(提交日期 2026-08-10),仓库内版本号 3.19.2。我们只读源码文本,没有安装、没有运行、也没有编译过这个项目。
四条门槛,两层口径
| 工具 | README「环境要求」 | 仓库里的另一处 | 出处 | 两层是否一致 |
|---|---|---|---|---|
| Node.js | 18+ | 22.12.0 | .node-version:1 | 不一致 |
| pnpm | 8+ | pnpm@10.12.3 | package.json:21 的 packageManager | 不一致 |
| Rust | 1.85+ | rust-version = "1.85.0" / channel "1.95" | src-tauri/Cargo.toml:9 / rust-toolchain.toml:2 | 仓库内部两处不同 |
| Tauri CLI | 2.8+ | @tauri-apps/cli 为 ^2.8.0 | package.json:23 | 一致 |
这张表的读法是:「README『环境要求』」那一列是声明层(写给人看的最低要求);「仓库里的另一处」加「出处」这两列合起来是落盘层(会被工具真正读取的固定值,以及它所在的文件与行)。四条里只有 Tauri CLI 那一条两层能对上。
反直觉的那一处:Rust 在同一个仓库里有两个数
Node 和 pnpm 那两条其实好理解——README 给的是「最低多少以上」,仓库文件给的是「实际钉在哪一版」,一个宽一个窄,方向一致。Rust 这条不一样,它的两个数都在仓库里,而且不同:
src-tauri/Cargo.toml:8-9:edition = "2021",rust-version = "1.85.0"rust-toolchain.toml:1-4:channel = "1.95",components = ["rustfmt", "clippy"],profile = "minimal"
Cargo.toml 那个 1.85.0 与 README 的「Rust 1.85+」是同一个口径,两处对得上。而 rust-toolchain.toml 钉的 1.95 比它高了十个小版本。
这两个文件在 Rust 生态里的分工不是一回事(以下是通用生态语义,不是该项目文档里写的内容,具体行为请以官方文档为准):Cargo.toml 的 rust-version 是包声明的最低支持版本,属于兼容性元数据;rust-toolchain.toml 是工具链管理器读取的固定工具链声明,落在仓库根目录,作用范围是这个目录下的构建。所以你在这个仓库里执行构建命令时,环境里究竟起作用的是哪一版,跟你照着 README 装了哪一版可能不是一回事。
按纪律,说到这里就停:我们不推断哪个数「才是对的」,也不推断为什么会有两个数。我们没有在本机编译过这个仓库,因此也不能告诉你 Rust 1.85 到底能不能把它编过去——这个问题只能你自己在自己的环境里试。
同一个 rust-toolchain.toml 里另外两行也顺带说明了这个文件想管什么:components 明确要求装 rustfmt 与 clippy,profile = "minimal" 则把默认组件集合压到最小。这两条和版本数无关,只是同在这个文件里一并声明,我们不推断作者为什么这么写。
pnpm 那一条,CHANGELOG 里有个补充
pnpm 的两层差异(README 8+ 对 package.json 的 pnpm@10.12.3)不止是个数字差,CHANGELOG 里记了一条与它直接相关的变更。
CHANGELOG.md:52(属于 ## [3.19.2] - 2026-08-06 这一条目下的 Internal 段)记录:CI 改为通过 Corepack 安装 pnpm,遵循 package.json 里的 packageManager 固定版本。这条记录我们只照抄,不替它补充「所以本地也该怎么装」——CHANGELOG 那一行说的是 CI,本地怎么装是另一回事,卡里没有的我们不写。
也就是说,pnpm 这一条的落盘层是 CI 与本地都会读的那个 pin,而 README 的「8+」是另一层的表述。两层各说各的,我们只陈述这个差异本身。
Node 那一条我们没有找到类似的补充记录:.node-version 里就孤零零一行 22.12.0,README 写 18+,两处并列。
Tauri 那一条别搞混:CLI 不是那个 crate
Tauri CLI 是四条里唯一两层一致的:README 写「Tauri CLI 2.8+」,package.json:23 的 devDependency @tauri-apps/cli 是 ^2.8.0,对得上。
容易搞混的是仓库里还有两个带 Tauri 字样的版本号,它们不是 CLI:
src-tauri/Cargo.toml:30:tauri = "2.8.2",features 为tray-icon/protocol-asset/image-pngsrc-tauri/Cargo.toml:23:tauri-build = "2.4.0"
这两个是 Rust 侧的库依赖与构建依赖,跟你装的那个命令行工具是不同的东西。看到 2.4.0 别以为 README 的「2.8+」写错了——它俩根本不在同一个坐标系里。顺带一提,SQLite 是通过 rusqlite = "0.31" 引入的,features 为 bundled / backup / hooks(src-tauri/Cargo.toml:76)。这三个 feature 名我们照抄自 Cargo.toml,它们各自具体意味着什么属于 rusqlite 的通用 feature 约定、不是该项目文档里写的内容,请以官方文档为准。
可复现的核查动作
这一篇的所有结论都能在两分钟内自己核一遍。在仓库根目录依次看这四个文件:
cat rust-toolchain.toml
cat .node-version
sed -n '1,10p;22,24p' src-tauri/Cargo.toml
sed -n '18,24p' package.json
然后打开 README_ZH.md 翻到「环境要求」小节(四条要求在 README_ZH.md:447-450),把上面四个文件里的数逐条对过去。比对的重点是这三组:
.node-version的一行 对 README 的 Node 条package.json的packageManager对 README 的 pnpm 条rust-toolchain.toml的channel对src-tauri/Cargo.toml的rust-version对 README 的 Rust 条(这一组是三处)
以上为按仓库中的文件位置组合的查看示例,我们没有在本机运行过,行号也会随版本变动,以你自己 clone 到的仓库内容为准。
什么时候这几个数才和你有关
这一条得说清楚,否则容易把不相干的读者吓住。
只装成品包的人,完全不受这四条影响。 README 的「环境要求」是开发环境要求,跟安装要求是两套东西:安装侧的口径写在另一处,是 Windows 10 及以上、macOS 12 (Monterey) 及以上、Ubuntu 22.04+ / Debian 11+ / Fedora 34+ 等主流发行版(README_ZH.md:353-355)。你从 Releases 下 msi 或 dmg,跟 Rust 装的是 1.85 还是 1.95 没有任何关系。
要从源码构建或者要提 PR 的人,这四条才是入口。相关的配套信息有两组,一起记下来:
开发脚本在 package.json:6-17:pnpm dev 实际是 pnpm tauri dev,pnpm build 是 pnpm tauri build,另有 typecheck、format、format:check、test:unit、test:unit:watch。
提 PR 前的三道门写在 README_ZH.md:582-584:pnpm typecheck、pnpm format:check、pnpm test:unit 全过。注意 format:check 这道门跟前面 rust-toolchain.toml 里的 components 是两码事——前者是 package.json 里的一个 pnpm 脚本,后者是 rust-toolchain.toml 声明要装的 Rust 组件(rustfmt 与 clippy),两者出处不同;各自具体查什么、装什么,以仓库配置为准。
还有一组固定值虽然不属于「版本门槛」,但同样是被钉死在仓库里、你构建时绕不开的:src-tauri/Cargo.toml:110-117 的 release profile 写了 codegen-units = 1、lto = "thin"、opt-level = "s"、panic = "unwind"、strip = "symbols",文件里的注释写明这么设的目的是压小 AppImage 的体积,同时保留 unwind 好让 panic hook 能抓到 backtrace。把它和前面四条放在一起看,你会发现这个仓库对「构建环境长什么样」是有一整套固定声明的,README 的「环境要求」只是其中面向人的那一层摘要。
至于「那我到底该装哪一版」,这个仓库没有给出一句话答案,我们也不替它给。能确定的只有:这几个数分别写在上面那几行里,你照着比对完,就知道自己环境里的每一个工具站在哪一层口径上。
最后重复一遍分寸:四条门槛的两层口径差异是可核实的事实,我们把每一处的文件与行号都标了出来,你可以自己去核。至于哪一处「才算数」、为什么没有同步、这对项目意味着什么,本文不做推断,也不拿它去评价这个项目——对完就停。
本文依据 CC Switch 官方仓库(github.com/farion1231/cc-switch)的 README、docs/ 下的用户手册与发布说明、
src/config/ 的预设定义与 src-tauri/src/ 的后端源码整理,核对日 2026-08-10,对应仓库快照 c39c903。
本文内容为仓库源码与文档口径,我们没有安装或运行过这个桌面应用,
因此不涉及界面外观、操作手感与切换速度的任何描述。
文中出现的阈值与默认值均为源码中的默认配置,不构成对实际运行结果的保证。
该项目仍在快速迭代,版本与默认值随时可能变动,请以仓库最新内容为准。