作为一个在 Node.js 生态里折腾了多年的开发者,我深知版本管理这件事有多让人头疼。你可能因为某个旧项目需要 Node 12,同时新项目又要求 Node 20,又或者你只是想尝鲜 nightly 版本但又怕影响现有环境。手动下载安装包、配置环境变量、反复卸载重装——这些我都经历过,真的效率太低了。
今天我要分享的是 Fnm(Fast Node Manager),一个由 Rust 编写的 Node.js 版本管理工具。它最大的优势就是快,快到你几乎感觉不到它的存在。而且它在 Windows 下的体验非常顺滑,配合 PowerShell 使用,切换版本几乎是瞬间的事。
这篇文章我会带你从零开始,在 Windows 上完整地安装和配置 Fnm,附赠我使用过程中的一些踩坑经验和排查技巧。无论你是刚入门的新手,还是想提升效率的老手,这篇都值得你收藏。
1. 为什么选择 Fnm 而不是其他工具
先聊几句背景。Node.js 的版本管理工具其实有不少选择,比如老牌的 nvm-windows、n,以及后起之秀 Volta 和 Fnm。我以前用过 nvm-windows,但它的切换速度实在有点拉胯,而且偶尔会出现命令不响应的现象。
Fnm 让我眼前一亮的原因有三点:
- 极速切换:因为它完全由 Rust 编写,运行效率非常高。实测在机械硬盘上切换版本也是秒级完成。
- 多平台支持:不只是 Windows,macOS 和 Linux 同样适用,如果你以后换了电脑系统也能无缝衔接。
- 全局配置能力:可以通过
.node-version文件自动切换版本,这意味着当你进入一个项目目录时,Fnm 可以自动帮你选中对应版本的 Node,完全不用手动干预。
而 Volta 虽然也很优秀,但它更倾向于“锁定工具链”而不是“管理多个版本自由切换”。如果你手头有多个项目,每个项目依赖不同 Node 版本,Fnm 的自动切换机制会更契合你的工作流。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 安装 Fnm 的两种方式
2.1 使用安装脚本(推荐)
在 Windows 上安装 Fnm,我个人最推荐使用 PowerShell 执行一条命令,简单粗暴:
powershell复制winget install Schniz.fnm
如果你还没安装 winget 或者版本比较老,可以先检查一下 Windows 系统更新。或者,也可以去 Fnm 的 GitHub Releases 页面手动下载 fnm-windows.zip 压缩包,解压后把 fnm.exe 所在路径加入系统 PATH 环境变量。
提示:手动下载的方式尤其适合那些网络受限、无法使用 winget 的环境。但一定要记得把解压目录加入 PATH,并重启终端。
2.2 通过 Scoop 包管理器安装
如果你已经在使用 Scoop 管理 Windows 软件,那安装就更方便了:
powershell复制scoop install fnm
我个人挺喜欢 Scoop 的,因为后续升级 Fnm 只需一条 scoop update fnm 即可搞定。winget 同样支持升级,但两者在有的时候代理环境下表现略有不同,大家可以按自己的习惯来。
3. 初始化 Fnm 环境
安装本身只是第一步,真正让 Fnm “跑起来”的是环境初始化。这一步是很多新手容易忽略的。装完 Fnm 后,在 PowerShell 里直接敲 fnm 大概率会提示“无法识别”,原因就是还没配置环境变量和自动加载脚本。
3.1 配置 PowerShell Profile
打开 PowerShell,执行以下命令创建 Profile(如果不存在的话):
powershell复制if (!(Test-Path -Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
然后编辑 Profile:
powershell复制notepad $PROFILE
在文件末尾加入 Fnm 的初始化脚本:
powershell复制fnm env --use-on-cd | Out-String | Invoke-Expression
保存后,重新打开 PowerShell 或手动执行:
powershell复制. $PROFILE
这一步做了什么?fnm env --use-on-cd 会输出一组环境变量和函数定义,其中最关键的是一个 Hook,它会监听你进入目录的行为。这样一来,一旦进入包含 .node-version 或 .nvmrc 文件的目录,Fnm 就会自动把当前环境的 Node 切换到对应版本。
3.2 支持 Cmder / Git Bash
很多 Windows 开发者不只用 PowerShell,还会用 Cmder 或 Git Bash。这里也顺带提一嘴。在 Git Bash 里,你可以在 .bashrc 中加入:
bash复制eval "$(fnm env --use-on-cd)"
Cmder 如果以 PowerShell 为核心,走上面的配置即可;如果用的是 Bash 模式,就跟 Git Bash 一样配置。
4. 核心操作:安装和切换 Node 版本
到这里,Fnm 已经在你的系统里“活了”。现在开始实际操作一下最核心的功能。
4.1 查看远端可用的 Node 版本
powershell复制fnm list-remote
这个命令会列出所有远端可安装的版本,包括 LTS 版本和最新版。输出量很大,我一般会配合 Select-String 或者 findstr 来过滤:
powershell复制fnm list-remote | Select-String "20"
4.2 安装指定版本
比如你要安装最新的 LTS 版本(假设是 22.x),可以执行:
powershell复制fnm install 22
这条命令中的 22 是主版本号,Fnm 会自动识别该主版本号下的最新版本并安装。如果你需要精确安装某个小版本,也可以写完整,例如 fnm install 20.18.0。
在安装过程中,Fnm 会从官方的 Node.js 分发源下载对应的压缩包,然后自动解压并配置本地路径。整个过程就像后台静默操作一样,几乎不打扰你。
注意:在部分 Windows 环境下,如果开启了某些严格权限策略,可能会提示无法加载
fnm.ps1脚本。解决办法是用管理员身份运行 PowerShell,执行Set-ExecutionPolicy RemoteSigned -Scope CurrentUser,然后重新加载 Profile 即可。
4.3 切换当前 shell 的版本
powershell复制fnm use 22
执行后,当前终端会话的 Node 就切换到了 22 版本。你可以用 node -v 验证一下。
另外,设置默认版本也很重要。默认版本意味着每次新开终端时自动加载的 Node 版本:
powershell复制fnm default 22
4.4 查看已安装的版本列表
powershell复制fnm list
它会列出所有本地已安装的版本,并用标记标明哪个是默认版本。看输出就一目了然。
5. 项目级自动切换版本
这才是 Fnm 的杀手锏。前面我们提到 .node-version 文件,它实际上就是一个纯文本文件,里面写着当前项目要求的 Node 版本号。例如:
text复制20
这个文件放进你的项目根目录。之后,当你用 cd 进入该目录时,Fnm 通过 --use-on-cd 的 Hook 会自动读取这个文件,并切换到对应的 Node 版本。
这套机制和 nvm 的 .nvmrc 是同样的思路,能很好地解决团队协作中的环境一致性问题。特别是当你接手一个新项目时,不需要问“你自己用的 Node 版本是多少”,看文件就知道了。
6. 版本安装后的全局工具问题
切换 Node 版本后,全局安装的工具链(比如 npm、yarn、pnpm)也会跟着变。这一点很多人没注意:全局工具是按 Node 版本分开保存的。
我给你演示一个实际场景:
powershell复制fnm use 20
npm install -g npm@latest
这里把 npm 升级到了最新版。但注意,这个“升级”只影响当前 Node 20 对应的全局环境。等你切回 Node 18 时,npm 会恢复到 Node 18 自带的那个版本,不会跟 Node 20 混在一起。
如果你希望某个工具在所有版本下都能使用,目前比较合理的办法是分别在各个版本下安装。好在 Fnm 的安装和切换都非常快,这也不算麻烦。
7. 使用中的常见报错与排查思路
用 Fnm 的过程中,我踩过不少坑,这里挑几个最常见的说一说。
7.1 “fnm 不是内部或外部命令”
这个问题的根本原因是 PATH 环境变量配置不正确,或者终端没有重新加载。你可以先检查一下:
powershell复制where.exe fnm
如果返回为空,说明 PATH 没有生效。去系统环境变量里检查是否有 Fnm 的安装目录,然后重新打开终端。
7.2 “error: Fnm could not find Node.js”
这个报错往往出现在你刚安装好 Fnm,但还没有安装任何 Node 版本时。解决方案很简单,执行 fnm install --lts 安装一个 LTS 版本,再 fnm default <version> 设为默认。
7.3 安装版本时报错 “version is not yet released or is not available”
其实有时候你输入 fnm install 24,但 Fnm 提示远端版本列表里没有 24.x。这可能是因为 Node.js 官方还没发布,或者你的 Fnm 版本过旧,还没同步到最新版本列表。建议先执行 fnm ls-remote 看看可用版本,确认版本号存在后精确安装。
7.4 PowerShell 执行策略限制
这是一个很经典的问题。执行 fnm env ... 时候报错提示“在此系统上禁止运行脚本”。解决方法就是设置当前用户的 ExecutionPolicy:
powershell复制Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
设置完成后,重新加载 Profile 即可。
8. 配合 IDE 与 CI 环境的实践
如果你用 VS Code,那 Fnm 基本是零障碍的。因为 VS Code 的终端会继承系统环境变量,你只需要在 VS Code 里打开一个新的终端,它就会自动使用你配置好的 Fnm 环境。
如果你用的是 WebStorm,可能需要在设置里把终端壳层改成 powershell.exe,确保 Fnm 的初始化脚本能够被加载。理论上没问题,只是需要注意,WebStorm 有时会默认使用 cmd.exe,这时候改动一下终端的启动配置即可。
在 CI 环境(比如 GitHub Actions)中也可以使用 Fnm。你只需在 workflow 里安装 Fnm,然后执行 fnm install 和 fnm use,就能快速构建针对不同 Node 版本的测试矩阵。这种方式比每次拉取一个 Node 镜像更快,尤其适合那些需要频繁测试多版本兼容性的项目。
9. 卸载 Node 和 Fnm 的注意事项
有些人可能是在已经安装过官方 Node.js 的情况下,再引入的 Fnm。这种情况下,老 Node 版本和新 Fnm 管理的版本可能会产生冲突。建议你把系统里原本的 Node.js 手动卸载干净,包括删除环境变量里的 NODE_HOME 或 NODE_PATH,再开始用 Fnm。
Fnm 本身的卸载很简单:只需要删除它的安装目录,然后清理环境变量和 Profile 里的初始化脚本。如果你是用 winget 安装的,执行 winget uninstall Schniz.fnm 即可。
10. 我目前的完整配置参考
最后,把我个人目前在 Windows 上的完整 Fnm 配置分享一下,供你参考。
我的 PowerShell Profile 里就一行核心配置:
powershell复制fnm env --use-on-cd | Out-String | Invoke-Expression
然后我管理着一个默认版本和一个长期维护版本:
powershell复制fnm default 22
fnm install 20
当我要切换项目时,进入项目目录就会自动切版本,几乎不需要手动干预。
在我实际使用 Fnm 这段时间里,最大的感受就是“无感”,它不像一个额外的工具,而更像是 Node 本身的一部分。切换版本瞬间完成,项目自动识别版本,全局工具隔离存储,一切都非常自然。
如果你还在用解压安装包、手动改 PATH 的方式来管理 Node 版本,真心建议试一下 Fnm。从安装到配置完成,你只需要一次投入,之后就是持续的便利。希望这篇分享能帮你少走一些弯路,如果配置过程中遇到问题,随时欢迎交流。
