news 2026/9/17 2:47:17

Windows上Node多版本管理最佳实践:Fnm安装配置与使用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Windows上Node多版本管理最佳实践:Fnm安装配置与使用指南

很多做前端和Node.js开发的朋友,在Windows上折腾Node版本时,应该都有过这种体验:项目A要Node 14,项目B要Node 18,全局装了吧,切版本就得手动下载安装包,环境变量改来改去,改完还得重开终端,一不小心还会把系统搞乱。后来出现了nvm-windows,确实方便了不少,但用起来总感觉有点笨重,切换速度也不够快,有时候装着装着还报错。

我自己也是被这个问题折磨了挺久,后来换到了Fnm(Fast Node Manager),算是彻底解决了我 Windows 上的 Node 版本管理焦虑。Fnm 是 Rust 写的,天生就快,而且原生支持 Windows,配置文件清晰,切换版本基本是毫秒级体验。这篇文章我就把这套在 Windows 上安装、配置、使用 Fnm 的实操记录完整梳理一遍,包括我踩过的坑、排查过的报错,以及配合 Shell 和 VS Code 的一些优化技巧。如果你也在为 Node 多版本切换头疼,或者想从 nvm-windows 迁到 Fnm,这篇应该能帮你省不少事。

1. 为什么我放弃 nvm-windows 换到 Fnm

先说清楚 Fnm 到底是什么。Fnm 是一个跨平台的 Node.js 版本管理工具,全称是 Fast Node Manager,核心卖点就是一个字“快”。它由 Rust 编写,没有运行时依赖,安装完是一个独立的 .exe 文件,不依赖系统全局的脚本解释器,所以启动和切换版本的速度比那些基于 Shell 脚本的工具快很多。

在 Windows 上,最流行的 Node 版本管理工具其实是 nvm-windows,它是按 nvm(Linux/Mac 上广泛使用的版本管理工具)的思路移植过来的。很多教程也推荐它,但我用下来有几个特别别扭的地方:

  • 切换版本后,新开的终端有时不会立刻生效,需要重启终端甚至重启电脑。
  • 安装新版本时下载速度不稳定,偶尔会卡住,报错信息也不直观。
  • 它的 Node 全局模块(npm 全局包)在切换版本后经常需要重新安装,因为每个版本对应独立的全局目录,切来切去很容易忘装。
  • 卸载时会在环境变量里留下残留,清理起来比较麻烦。

Fnm 的出现正好解决了这些痛点。它支持.nvmrc文件(项目指定 Node 版本),支持根据目录自动切换版本,支持 node 版本别名,而且配置全部集中在一个 JSON 文件里,想备份就备份,想迁移就迁移。最关键的是,它不需要管理员权限就能装到用户目录,对没有管理员权限的公司电脑来说非常友好。

我在实测中的感受是:用 Fnm 切换 Node 版本,速度体感上是瞬间完成的,终端里敲完命令立刻就能node -v验到新版本,完全不需要关终端。这种体验和之前 nvm-windows 的“粘滞感”形成鲜明对比。

当然,Fnm 也不是没有缺点。比如它的 Shell 集成需要手动在 PowerShell 配置文件中加一段代码,如果你对 PowerShell 配置文件不熟悉,第一次配置时可能有点懵。这个我下面会详细讲,照着做就行。

2. 安装方式的选择与实操对比

Fnm 在 Windows 上提供了好几种安装方式:winget、scoop、chocolatey,以及直接下载二进制包手动安装。我实际试过 winget、scoop 和手动安装,说说我的感受。

2.1 通过 winget 安装

winget 是 Windows 10/11 自带的包管理器,Windows 10 1709 之后的版本基本都有。安装 Fnm 只需要一条命令:

winget install Schniz.fnm

这条命令会自动下载 fnm 的最新 release 版本并配置环境变量。胜在省心,不用自己去官网找下载链接。不过有个小问题:winget 安装后,会让你重新打开终端才能生效,而且默认安装目录在用户目录下的AppData\Local\fnm,后续找配置的时候知道这个路径就行。

2.2 通过 scoop 安装

如果你已经装了 scoop,用 scoop 安装也很方便:

scoop install fnm

scoop 的优点是它会帮你把 fnm 的可执行文件放在一个统一的目录下,后续升级直接scoop update fnm就行。它默认安装的是最新版,而且 scoop 有一个特点:部分 GUI 应用还会创建快捷方式,但 fnm 是纯命令行工具,所以只在 shims 目录生成一个链接。

2.3 手动下载二进制包

如果你不想装包管理器,或者公司电脑装软件需要审批,可以直接去 fnm 的 GitHub Releases 页面下载fnm-windows.zip。解压后你会得到一个fnm.exe,把它放到你想要的目录就可以了,比如D:\Tools\fnm

手动安装的好处是位置完全可控,我是放在D:\Tools\fnm\fnm.exe,然后手动配置 Path 环境变量。这样做的缺点是升级时得自己再下载覆盖,没办法一条命令搞定。对于日常使用来说,其实没太大影响,反正 Fnm 本身更新频率不算高。

2.4 三种方式的优缺点速查

我想把这几种方式的特点直接放在下面这张表里供你参考:

安装方式优点缺点适合场景
winget自带的命令,不用额外装东西安装目录藏在 AppData,要找大部分人,最无脑
scoop升级方便,和现有工具链统一需要先装 scoop,有些网络环境下载慢已经在用 scoop 管理工具的人
手动下载路径自己定,完全可控升级要手动,环境变量得自己配公司电脑没管理员权限或特殊场景

我个人的建议是:如果你比较懒,就直接 winget。如果你想对安装位置和配置路径有绝对掌控,就手动下载。说实话,后面接 Shell 集成的时候都要手动操作一步,所以选哪种安装方式对最终配置的影响不大。

3. 环境变量配置和目录结构规划

无论你选哪种安装方式,配置环境变量这一步几乎都逃不掉。Fnm 安装后,需要两个环境变量:一个是让系统能找到fnm.exePath变量,另一个是指定「Fnm 安装 Node 版本和缓存的目录」的FNM_DIR变量。很多人只配了 Path,结果 Fnm 能用但下载的 Node 版本不知道被扔到哪里,后面排查起来就会绕弯路。

3.1 Path 环境变量

先说 Path。如果你用 winget 或 scoop 安装,安装工具通常会自动设置好 Path,不需要手动加。如果是手动下载解压的,需要把fnm.exe所在的目录添加到用户级别的 Path 环境变量里。

具体操作为:按 Win 键,输入“编辑账户的环境变量”,打开后选中上面的“用户变量”里的Path,点击“编辑”,然后“新建”,把 fnm.exe 的路径粘贴进去(比如D:\Tools\fnm),一路确定就好。

添加完后,新开一个终端,输入:

fnm --version

如果能输出版本号,说明 Path 配置成功了。如果提示“不是内部或外部命令”,多半是环境变量没生效,或者终端没有重启,重新打开一个终端窗口再试。

3.2 FNM_DIR 环境变量

FNM_DIR 是 Fnm 用来存放所有 Node.js 版本和默认模块的目录。如果不设这个变量,Fnm 在 Windows 上会默认使用%AppData%\fnm,也就是用户的 AppData 目录下。这个目录在 C 盘,如果你的 C 盘空间紧张,或者你想把缓存和 Node 版本移到其他盘,就需要手动指定 FNM_DIR。

我就是把 FNM_DIR 指到了D:\Tools\fnm_data,理由是:C 盘是固态系统盘,攒太多 Node 版本占空间不说,万一系统重装还得重新下载。放在 D 盘的数据盘上,系统崩了也不影响这些已下载的 Node 版本。

设置方法:还是打开“编辑账户的环境变量”,在用户变量区域,点击“新建”,变量名填FNM_DIR,变量值填你期望的目录路径(例如D:\Tools\fnm_data),确定即可。注意,这里的目录不要求提前存在,Fnm 在首次运行时如果发现目录不存在会自动创建。

3.3 目录结构说明

当你设置了 FNM_DIR 并安装了一个 Node 版本后,这个目录下会生成几个子目录:

子目录作用
node-versions存放所有通过 Fnm 下载的 Node.js 版本,每个版本一个子目录
aliases存放你定义的版本别名(比如defaultlts-latest
shims存放接管系统命令的 shim 文件(Windows 上也有,用于目录自动切换)

理解这几个目录的作用,对后续排查问题很有帮助。比如你切换版本不生效,先看看node-versions里到底有没有这个版本;如果设置了别名但找不到,就去aliases目录看看。总之,把 FNM_DIR 想成“Node 版本的仓库”,Path 只是“仓库入口的指示牌”,两个都要有系统才能正常运转。

4. PowerShell 集成与自动切换配置

在 Windows 上使用 Fnm,推荐搭配 PowerShell 或 Windows Terminal。这里有个关键点:如果你只想手动敲fnm use 18来切换版本,那不需要额外配置。但如果你想实现「进入某个目录,自动切换到对应 Node 版本」的体验,就必须配置 Shell 集成。这个集成的作用是,每次打开终端时,自动把 Fnm 管理的当前 Node 版本绑定到当前的 Shell 会话中。

4.1 生成系统的初始化脚本

Fnm 提供了一个命令来生成不同 Shell 的配置文件片段:

fnm env --use-on-cd

其中--use-on-cd表示在切换目录时自动启用对应的 Node 版本。

把这个命令产生的输出写入 PowerShell 的配置文件$PROFILE就可以实现自动化。你不需要手动去抄文件内容,可以直接用重定向:

fnm env --use-on-cd | Out-String | Invoke-Expression

但这是临时执行的写法。想永久生效,需要把这个命令加到当前用户的 PowerShell 配置文件中。在你的 PowerShell 中执行:

notepad $PROFILE

如果提示找不到该文件,先执行:

New-Item -Path $PROFILE -Type File -Force

然后打开的文件里,把下面这行粘贴进去:

fnm env --use-on-cd | Out-String | Invoke-Expression

保存关闭后,重新打开一个 PowerShell 窗口,输入fnm current,如果能看到当前 Node 版本,就说明 Shell 集成生效了。

4.2 Windows Terminal 里新增 PowerShell 作为默认终端

Windows 11 自带 Windows Terminal,这是微软官方推荐的终端程序,支持多标签页、主题配置,和 Fnm 配合起来思路很顺。如果你在用 Windows Terminal,建议把默认终端设置为 PowerShell,然后在设置里指定启动时执行的命令行参数。

具体操作为:打开 Windows Terminal,按Ctrl+,打开设置,在“配置文件”里找到“Windows PowerShell”或“PowerShell”,点击“默认”按钮把它设为默认配置文件。设置好后,每次打开 Windows Terminal 的第一个标签页就是 PowerShell,自动加载你配置好的$PROFILE文件,Fnm 的集成也自动生效。

4.3 VS Code 集成怎么写

VS Code 是很多 Node 开发者的主力编辑器。在 VS Code 的集成终端里,如果打开终端时没有加在 Fnm,手动敲fnm use 18其实也还好,但我建议在 VS Code 设置里把 PowerShell 设置为默认终端配置文件,并确保它加载了$PROFILE

打开 VS Code 的设置(Ctrl+,),搜索“terminal.integrated.defaultProfile.windows”,在可选列表里选择“PowerShell”。然后重新打开终端,输入fnm current测试,如果输出版本号就正常了。

可能有人会遇到 VS Code 里能fnm --version,但node命令却找不到的情况。这是因为 VS Code 的终端环境变量没有刷新。解决的办法是:完全关闭 VS Code,然后新开一个 PowerShell,确认node命令能正常用,再打开 VS Code。VS Code 启动时会继承当前环境变量,所以只要 PowerShell 里正常,VS Code 里面也跟着正常。

5. 日常安装、切换版本的实操命令

到了这一步,Fnm 基本装好、集成配好了,接下来就是高频使用环节。我把自己日常用到的 Fnm 命令整理成一个速查表,方便你以后直接对照查询。

命令说明
fnm list列出所有已安装的 Node 版本
fnm list-remote列出所有远程可用的 Node 版本
fnm install 18安装 Node.js 18 的最新版
fnm install 20安装 Node.js 20 的最新版
fnm use 18切换当前终端到 Node 18
fnm default 18设置全局默认 Node 版本(新终端默认用这个)
fnm current查看当前终端使用的 Node 版本
fnm uninstall 18卸载 Node 18
fnm alias 18 myapp给 Node 18 设置一个别名(比如myapp

几个需要注意的命令细节:

  • fnm install 18只会安装 Node 18 的最新 patch 版本,比如 18.20.x。如果项目需要指定到18.16.0,直接写fnm install 18.16.0就好。
  • fnm default 18相当于设置了默认版本,但已经打开的终端不会变,只有新开的终端才会应用默认版本。这个行为和 nvm-windows 也是类似的。
  • 切换版本后,全局安装的 npm 包(比如npm install -g yarn装的 yarn)会因为 Node 版本的改变而“消失”,因为每个 Node 版本有独立的全局模块目录。这一点是 Node 版本管理工具的通用特性,不是 Fnm 的 bug。解决方案是切换到对应版本后重新安装全局包,或者用fnm exec --using=18 npm install -g yarn在指定版本下安装全局包。

顺带提一个很多人问的问题:切换 Node 版本后,npm会自动跟随吗?答案是会。Fnm 管理的是整个 Node 发行版,而 npm 随 Node 附带,所以切换 Node 版本后,npm也会自动变成那个版本对应的 npm。这在 Windows 上非常重要,因为 npm 版本差异较大时,package-lock.json的处理逻辑会有细微差异,切换版本能避免很多莫名其妙的 lock 文件冲突。

5.1 使用 .nvmrc 实现项目级版本锁定

这是 Fnm 最让我喜欢的功能之一。和 nvm(Linux/Mac)一样,Fnm 也支持.nvmrc文件。你可以在项目根目录创建这个文件,里面写上项目要求的 Node 版本号(比如18或者18.20.0),然后当你进入这个目录时,Fnm 的--use-on-cd就会自动读取这个文件并切换到对应版本。

创建 .nvmrc 的方法:

node -v > .nvmrc

或者手动创建文件,写入对应版本号。我通常会在项目里固定.nvmrc文件并提交到 Git 仓库,这样团队里的其他同事 clone 下来后,第一次进入目录时自动切换版本,不会出现“我本机能跑你本机跑不了”的尴尬局面。

具体到团队协作,我建议在项目 README 里写一句“要求 Node 版本见 .nvmrc”,这样即使同事不熟悉 Fnm,也知道项目有固定版本要求。

5.2 配合 fnm exec 在单个命令中指定版本

还有一种场景:你想临时在特定 Node 版本下执行某个命令,但不想切换全局版本。比如,一个项目依赖 Node 16,但你当前默认是 Node 20。你可以用:

fnm exec --using=16 npm install

这样会临时用 Node 16 执行npm install,而不会动你终端的默认版本。这个命令特别适合给老项目打补丁、或者验证某个包在不同 Node 版本下的兼容性。

6. 常见问题排查与避坑指南

这里必须分享一些我实际踩坑总结出来的经验,没有这些,你按照教程操作一遍,可能还是会遇到各种意外。这些问题如果不提前了解,可能会卡你半小时甚至一下午。

6.1 打开新终端提示fnm 不是内部或外部命令

这是 Path 环境变量没配好,或者终端没有重新打开导致的环境变量缓存问题。解决步骤:

  1. 先确认fnm.exe所在目录确实在 Path 里(打开“编辑账户的环境变量”检查)。
  2. 确认后,新开一个终端窗口(不是新开标签页,最好是完全退出终端程序再启动)。
  3. 如果还不行,执行where fnm,看系统能不能搜到。如果提示找不到,说明 Path 里没有正确包含该目录,再检查一遍路径是否写错。
  4. 注意区分用户变量和系统变量。如果你把 Path 加在了系统变量里,当前已经打开的终端软件(包括 VS Code)都需要完全重启才能读取到。

6.2 fnm 能列出远程版本但 install 时特别慢或失败

这在 Windows 上比较常见,源于 Fnm 默认从 Node 官方源下载,国内网络环境偶尔会不稳定。解决办法是配置镜像源。Fnm 支持通过环境变量FNM_NODE_DIST_MIRROR指定 Node 发行版镜像地址。

在设置环境变量时,新建一个用户变量:

FNM_NODE_DIST_MIRROR=https://npmmirror.com/mirrors/node/

这样再执行fnm install 20时,就会从国内镜像下载,速度快很多。这个镜像源是 npm 官方在国内的同步镜像,长期可靠。

6.3 切换版本后,终端里的 node 还是旧版本

这种情况一般发生在你配置了 Shell 集成,但没有用fnm env初始化当前的 shell 会话。你敲fnm use 20,Fnm 只是修改了当前会话的环境变量,但如果 Shell 配置没有正确加载,可能不会生效。

解决方法是确认$PROFILE文件里已经有:

fnm env --use-on-cd | Out-String | Invoke-Expression

然后重启终端。如果你不想改$PROFILE,也可以用临时方案:

fnm env | Out-String | Invoke-Expression

手动执行一次,当前终端会立刻可用,但新终端不会保留,所以最终还是要配置$PROFILE

6.4 系统之前装过 Node.js,Fnm 安装后 node 命令冲突

这个问题很有意思。如果你电脑上之前已经用官方安装包安装过 Node.js,安装包里会往系统 Path 里注入 Node.js 的安装目录。之后你又装了 Fnm,运行时node命令到底用哪个,取决于 Path 里哪个目录排在前面。

Fnm 的做法是,在fnm env初始化时会把 Fnm 的 shims 目录放在 Path 最前面,从而优先使用 Fnm 管理的 Node。但如果你没有配置 Shell 集成,直接敲node -v,系统找到的可能是原来的 Node.js。

我从 nvm-windows 迁移到 Fnm 时,就在这一步被坑过。系统里残留的旧 Node 安装目录一直在 Path 里,导致 Fnm 切换版本一直“看起来不生效”。后来我把旧的 Node.js 安装目录从 Path 中删除(保留文件夹作为备份),再刷新环境变量,Fnm 就完全正常了。

建议做法:在安装 Fnm 并确认它能正常管理版本后,把原来的 Node.js 安装程序卸载或者手动移除其 Path 目录。如果你有老项目依赖全局包(比如老 npm 包),可以先记录一下全局包列表(npm list -g --depth=0),然后在 Fnm 的默认版本下重新安装。

6.5 npm 全局包在切换版本后丢了

前面提到过,这是所有 Node 版本管理工具的共同特性:每个版本有独立的全局安装目录。我在切换版本时习惯用fnm exec --using=当前版本 npm install -g <包名>来在特定版本下安装包,这样切换版本后也不会丢太多东西。

我的通用做法是:列出经常用的全局包清单,在系统默认 Node 版本下统一安装一次,比如 yarn、pnpm、typescript、@vue/cli、nodemon 等。这样大部分时间用的默认版本都有这些工具,切到其他版本临时跑项目时,通常也不需要全局包。

6.6 设置 FNM_DIR 后,之前安装的版本找不到了

这是自己坑自己的一种情况:我先用默认的%AppData%\fnm安装了几个 Node 版本,后来又设置了FNM_DIR指向 D 盘。结果fnm list显示空列表,因为 Fnm 只看 FNM_DIR 里面的内容。

解决办法很简单:把原来的 Node 版本文件夹完整移动到新的 FNM_DIR 目录下,目录名保持 node-versions 不变即可。或者直接重新下载(如果网络快的话,重下也可能更省事)。

7. 我的最终推荐配置与几点心得体会

最后分享一个我目前在用的推荐配置结构,如果你完全照着做,基本可以少走很多弯路:

  1. 用 winget 安装 Fnm:winget install Schniz.fnm
  2. 设置用户环境变量FNM_DIRD:\Tools\fnm_data(记得用你自己的路径)
  3. 在 PowerShell 配置文件$PROFILE添加一行:fnm env --use-on-cd | Out-String | Invoke-Expression
  4. 设置默认 Node 版本:fnm install --lts&&fnm default lts-latest
  5. 命令行工具推荐直接用 Windows Terminal 的 PowerShell 配置,关闭后重开终端
  6. 项目根目录统一维护.nvmrc

这样一套配置完成后,你打开终端进入项目目录,Fnm 会自动读取.nvmrc并切到对应 Node 版本,你甚至感觉不到 Fnm 的存在——这种“隐于无形”的体验,才是一个好版本管理工具该有的样子。

在我个人的实际使用中,Fnm 最让我满意的一点是它的命令响应速度。之前用 nvm-windows 的时候,敲一条nvm use 16往往要等半秒到一秒,而 Fnm 基本是即敲即得。可能有朋友觉得半秒不算什么,但当你一天内要频繁切换版本跑不同项目的时候,这种感觉还是很明显的。

另外,Fnm 的跨平台特性也很加分。正常情况下我白天在 Windows 台式机上写代码,晚上偶尔用笔记本电脑(Linux 或 macOS)继续,两边的 Fnm 命令几乎一模一样,不用学两套工具,体验是延续的。这一点对经常在家和公司之间切换设备的开发者来说,算是隐形福利。

如果你还在用 nvm-windows 或者手动改环境变量来管理 Node 版本,我真心建议你试一下 Fnm,整个配置过程不超过十分钟,但省下来的时间绝对能值回这十分钟。最后还有一个实用小技巧:更新 Fnm 时,不用卸了重装,直接到 GitHub Releases 页面下载新版本的压缩包覆盖旧文件就行,配置文件和已安装的 Node 版本完全不受影响。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 2:45:59

2026年最值得安装的6款黄金软件清单

每年一到整理软件清单的时候&#xff0c;总有人跑来问我同一个问题&#xff1a;2026年了&#xff0c;到底哪些软件值得装&#xff1f;说实话&#xff0c;软件圈子的更新换代比手机还快&#xff0c;但总有那么几款&#xff0c;无论新词怎么炒、竞品怎么追&#xff0c;用户好评度…

作者头像 李华
网站建设 2026/9/17 2:45:54

Git提交历史与版本回退实战:从统计commit到reset/revert

刚接触Git那阵子&#xff0c;我特别喜欢在项目里改几行就git commit -m "update"一下&#xff0c;提交记录刷得飞起。直到有一天领导突然问我“这个模块你到底提交过多少次、都动了点什么”&#xff0c;我盯着终端愣了半天&#xff0c;发现自己除了会无脑提交&#x…

作者头像 李华
网站建设 2026/9/17 2:45:39

GameDevMind 游戏开发技术图谱:项目定位、内容边界与高效使用指南

GameDevMind 游戏开发技术图谱&#xff1a;项目定位、内容边界与高效使用指南 【免费下载链接】GameDevMind 最全面的游戏开发技术图谱(Game Development Map)。帮助游戏开发者们在已知问题上节省时间&#xff0c;省出更多的精力投入到更有创造性的工作中去。 项目地址: http…

作者头像 李华
网站建设 2026/9/17 2:44:32

UEFI网络启动失败蓝屏:EFI Network boot failed原因与修复

1. 这个蓝屏到底在说什么&#xff1f;别被“EFI Network”四个字吓退你盯着屏幕&#xff0c;冷汗刚冒出来——黑底白字的蓝屏上赫然写着&#xff1a;EFI Network 0 for IPv4 (XX-XX-XX-XX-XX) boot failed.不是熟悉的0x0000007B、0xc000021a&#xff0c;也不是驱动签名错误或nt…

作者头像 李华
网站建设 2026/9/17 2:43:16

Ubuntu下海康MVS V4.3.0安装配置与SDK开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华