
Windows 上装 Node.js不是下载个 msi 双击Next就完事了。官网安装包适合只用一个版本的人可一旦你手头同时有老项目要 Node 16、新项目要用 Node 22或者你想试试最新的大版本又不想把现有环境搞坏就会立刻发现Windows 上的 Node 版本管理真的需要一个像样的工具。我用过一段时间的 nvm-windows后来换成了 Rust 写的 fnmFast Node Manager在 Windows 上安装、配置、日常使用都顺了很多。这篇博文就完整记录一下我在 Windows 上的 fnm 安装和配置过程从零开始把原理、步骤、踩坑都讲清楚。fnm 的核心思路很简单所有 Node 版本都下载到一个统一目录里用户在终端里切换时它动态修改当前 Shell 的 PATH指向某个具体版本。整个过程不需要管理员权限也不会污染系统全局变量。对 Windows 用户来说这几个特性尤其值钱因为你如果用过 nvm-windows 就会知道老方案经常会留下一些环境变量残留今天解决了这个项目明天那个项目又报错。如果你是第一次用版本管理工具也可以照着做。fnm 的命令设计比较友好日常基本只需要会 install、use、default、list 这几个命令就能干活。下面我把安装、终端配置、项目自动切版本、IDE 集成、常见报错这几块都展开讲。1. Node 版本管理在 Windows 上为什么难以及 fnm 是怎么拆解的1.1 版本冲突是前端项目的常态不是你电脑的问题很多人第一次意识到需要版本管理工具是在这种场景下电脑上装的是 Node 18项目 A 是两年前的老项目用了 Node 16 才稳定项目 B 是新项目脚手架要求 Node 20 以上。你卸载重装 Node装完 A 好了 B 挂了装完 B 好了 A 又不行了。这种局面不是你的运维能力问题而是 Node 版本本身迭代太快不同项目对运行时版本有不同要求。懂行的人会跟你提 nvm但那是 macOS/Linux 上比较顺手的方案。Windows 上大家最常提到的是 nvm-windows但它本质上是一个独立项目和 Linux 上的 nvm 不是同一个东西行为差异也不小。还有 Volta、nvs 这些工具各有各的思路。fnm 在这个生态里属于后起之秀。它是用 Rust 写的启动速度比老一批用脚本或 C 写的工具快很多而且不是靠读一个 .nvmrc 然后提示你手动切换这种半自动方式而是真的能在进入目录时自动切版本。这个自动切在 Windows 上尤其重要因为 Windows 的 PATH 刷新机制本来就比 Unix 麻烦手动切换几次就容易乱。1.2 fnm 相比 nvm-windows 到底强在哪我当初换到 fnm不是因为 nvm-windows 完全不能用而是它有几个痛点我实在受不了第一个痛点是慢。每次执行 nvm list、nvm use 都要等一下虽然不至于等半天但对比 fnm 的即时响应体感差距很明显。第二个痛点是环境变量残留。nvm-windows 通过注册表或系统环境变量维护当前 Node 路径如果某次切换失败或者终端没重开你很容易出现明明切到 Node 20 了node -v 还是 Node 18的情况。第三个痛点是自动切换能力弱nvm-windows 虽然在项目里放 .nvmrc 也能用但进入目录自动执行 nvm use这种体验需要额外配置Windows 自带的命令提示符和 PowerShell 下体验都不够顺。fnm 的做法不太一样。它把每个 Node 版本放在FNM_DIR/node-versions/版本号/installation下切换版本时会生成一个临时的 Shell 环境把当前要用的 Node 路径塞进当前进程的 PATH 里。因为是当前终端进程内生效所以你可以开着两个终端一个跑 Node 18一个跑 Node 22互不干扰。这在调试多个项目时非常舒服。1.3 用之前先理解三个目录概念配置 fnm 前我先说清楚三个概念后面遇到问题你就不会懵。一是FNM_DIR这是 fnm 的根目录默认在%APPDATA%\fnm。所有 Node 版本、别名、临时链接都放这里面。如果你想把版本数据放到 D 盘或公司要求的目录可以提前设置FNM_DIR环境变量。二是当前终端路径。fnm 不像传统安装包那样把 node.exe 直接复制到系统目录它通过修改当前终端的 PATH 来实现切换。所以在终端里运行 fnm use只是改了当前这个终端的 PATH并不会改系统全局 PATH。这也是它不需要管理员权限的原因之一。三是 Shell Hook。fnm 的自动切换依赖 shell 启动时执行一段初始化脚本这段脚本主要做两件事加载默认 Node 版本、注册目录切换钩子。Windows 下最常用的 Shell 是 PowerShell所以配置的重点就是往 PowerShell profile 里写入fnm env那一段。后面我会专门讲。2. 安装 fnm 的三条路winget、Scoop 和免安装包2.1 用 winget 安装适合绝大多数人Windows 10 1709 之后的系统基本都自带 App Installer也就能用 winget 了。安装命令很简单winget install Schniz.fnm装完之后先别急着用关掉当前终端重新开一个新的。因为 winget 会往 PATH 里加 fnm 的安装目录但已经开着的终端里 PATH 不会自动刷新。重新打开终端后运行fnm --version能看到版本号就说明装上了。这条命令适合绝大多数人前提是你的 Windows 版本不太老或者 winget 可用。如果你在旧版 Win10 上发现 winget 不存在可以先去应用商店装 App Installer或者直接用后面的免安装包方案。2.2 用 Scoop 安装适合本来就用 Scoop 管理软件的人Scoop 在开发者圈子里口碑不错核心思想是每个软件装在自己的目录里不用搞一堆安装向导。如果你已经装了 Scoop那么在 Windows Terminal 或 PowerShell 里执行scoop install fnmScoop 会自动处理可执行文件的 shim也就是会在 Scoop 的 shim 目录里生成一个 fnm 入口。这样你同样只需要重开终端就能用。Scoop 的好处是后续更新方便以后要升级 fnm直接scoop update fnm如果你既装了 winget也装了 Scoop用哪个都行不必纠结。真正要注意的是别两个都装否则你可能会遇到fnm 版本对不上这种低级困惑。2.3 免安装压缩包适合公司电脑或不想装包管理器的情况有些公司电脑被锁得很死或者你对多装一个包管理器有顾虑那就直接下载免安装版。fnm 的 GitHub Releases 页面提供了fnm-windows.zip下载后解压到比如D:\Tools\fnm然后把D:\Tools\fnm加到用户 PATH 里。添加 PATH 的步骤再啰嗦一下Win R 输入sysdm.cpl切到高级选项卡点环境变量在用户变量里找到 Path新建一行填D:\Tools\fnm确定保存。之后重新打开终端验证fnm --version。这里有个小建议如果你打算长期用最好把版本数据也放到非系统盘尽量避免让 AppData 越来越肥。可以手动创建FNM_DIR环境变量指向D:\Tools\fnm-datasetx FNM_DIR D:\Tools\fnm-data设置完这个变量后再执行的 fnm install 都会把 Node 版本装到D:\Tools\fnm-data下。setx只对新开的终端生效所以设置完记得把终端全部关掉重开。注意FNM_DIR 的路径里尽量不要有空格和中文。Windows 下的很多工具对中文路径支持不好Node 编译原生模块时也经常因为路径问题出幺蛾子。2.4 装了包管理器版本和压缩包版本配置逻辑一样吗一样也不一样。不管是 winget、Scoop 还是压缩包装的fnm 的可执行文件都是同一个核心命令一样。区别只在于安装目录不同、PATH 是否已经自动处理好。所以下面的 PowerShell 配置对所有安装方式都适用。3. 让 PowerShell 每次开终端都能加载 fnm3.1 把fnm env --use-on-cd写进 profile在 Linux/macOS 上很多工具靠往.bashrc或.zshrc里加一行eval $(fnm env)来初始化。Windows 上的 PowerShell 对应的文件叫 profile路径可以通过变量$PROFILE查看echo $PROFILE大概率会输出类似C:\Users\你的用户名\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1的路径。如果你的 PowerShell 是 7路径会在Documents\PowerShell\Microsoft.PowerShell_profile.ps1下。两个版本不共享 profile 文件所以如果你两个都用需要都配置一遍。profile 文件如果不存在先执行New-Item -ItemType File -Path $PROFILE -Force然后打开编辑notepad $PROFILE在文件里加上这一行fnm env --use-on-cd | Out-String | Invoke-Expressionfnm env会输出一段 PowerShell 脚本--use-on-cd表示进入目录时自动读取 .node-version 并切换 Node 版本Invoke-Expression负责执行这段脚本前面的Out-String是为了防止这段多行输出在管道里被拆成多行导致执行出错。保存后新开一个终端运行fnm current如果没报错还能看到当前默认版本说明配置成功。这时候函数fnm env --use-on-cd已经挂到当前 Shell 里了。3.2 PowerShell 执行策略最常见的第一次翻车点Windows 默认的 PowerShell 执行策略是 Restricted这种情况下 profile 脚本可能根本不会执行你会遇到配置了 profile 但 fnm 根本没生效的怪问题。解决办法是给当前用户设置 RemoteSigned。RemoteSigned 的意思是本地脚本可以跑从网上下载的脚本必须带可信签名。fnm 的脚本是本地生成的不受影响。Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser这个命令不需要管理员权限因为它只改当前用户的策略。改完再重开终端验证。如果你所在环境的组策略强制禁止终端会提示你无权修改那就需要走管理员流程或者用免安装包配合 cmd 启动方案后面我会讲一种折中思路。3.3 如果你还在用 cmd 或 Cmder能不能配置cmd 没有 profile 文件但 fnm 是支持 cmd 的。在 cmd 里可以这样初始化echo off for /f tokens* %%i in (fnm env --use-on-cd --shell cmd) do %%i把这四行存成一个fnm-init.cmd放到一个固定目录比如D:\Tools\fnm\fnm-init.cmd。然后在 Windows Terminal 的配置文件里把你的 cmd 配置文件的命令行参数改成commandline: cmd.exe /k D:\\Tools\\fnm\\fnm-init.cmd或者去注册表HKCU\Software\Microsoft\Command Processor\AutoRun里设置启动时执行这个脚本。AutoRun 会影响全局 cmd如果不是很有把握不建议随便改注册表。Cmder 本质上是 cmd 的加强版也可以走同样思路。但说实话现在 Windows 上开发我更推荐直接用 Windows Terminal PowerShell 7体验差距不是一点半点。如果你是新手没必要在 cmd 上花太多时间配自动切换。3.4 多了一个 fnm终端的 PATH 会不会越来越乱不会。fnm 修改的是当前进程的 PATH而不是系统 PATH。每次开终端它会重新计算一个临时 PATH把你的 Node 版本目录加进去。你可以在 PowerShell 里运行$env:Path -split ; | Select-String -Pattern fnm看到的结果会是类似C:\Users\xxx\AppData\Roaming\fnm\multishells\xxxxx这个目录是 fnm 为当前终端会话创建的临时链接目录目录里放着 node.exe、npm 等入口文件。这样做的好处是多个终端可以各自指向不同 Node 版本且不需要反复改写系统环境变量。4. 日常安装切换 Node 版本从手动到项目自动锁定4.1 核心命令安装、列表、切换、默认版本配好上面的环境之后接下来是用起来。最常用的命令我列一下# 查看远程有哪些版本 fnm ls-remote # 安装一个最新 Node 版本 fnm install latest # 安装某个 LTS 大版本 fnm install --lts # 安装指定大版本的最近小版本 fnm install 22 # 安装精确版本 fnm install 22.11.0 # 查看已安装版本 fnm ls # 切换当前终端到某个版本 fnm use 22 # 查看当前终端的 Node 版本 fnm current这里有个细节fnm install 22会帮你解析到 22 这个 major 版本下最新的可用版本所以日常用大版本简写就够了。如果项目里对版本要求很严格比如锁死了 22.11.0那就用精确版本号安装。切换版本后建议习惯性验证一下node -v npm -v如果你看到的 node 版本没变多半是 PATH 里还有其他 Node 入口在干扰这个我在后面的排查章节再说。4.2 设置默认版本新终端一开就是它我们不希望每次开终端都要手动fnm use所以需要设置一个默认版本。命令是fnm default 22这条命令本质上是把 22 这个版本注册为新的 default 别名。以后再开终端fnm 会默认使用这个版本。如果哪天你想把默认版本切回 20执行fnm default 20也可以手动管理别名fnm alias 22.11.0 default fnm unalias default我在多个 Node 版本之间穿梭时最喜欢这套逻辑默认用一个稳定的 LTS某个项目需要特殊版本时进入项目目录自动切换。4.3 用 .node-version 实现项目自动切换这是 fnm 最提升幸福感的功能。在项目根目录下新建一个.node-version文件内容只写版本号22.11.0或者写成大版本22然后保证你的 PowerShell profile 里是fnm env --use-on-cd而不是fnm env。这样当你cd进入这个目录时fnm 会读取.node-version并自动执行fnm use。如果你的项目以前用的是.nvmrcfnm 也会读取。但我个人更推荐新建.node-version因为它是目前更多工具共同认可的格式将来你换 asdf、mise 之类的工具也能无缝衔接。有一点要提醒自动切换不是万能的。如果你是直接在项目目录里右键打开终端正常情况下终端启动时会先加载默认版本然后触发目录切换逻辑最终应该切到项目指定版本。如果没切先确认你的 profile 里确实加了--use-on-cd而不是只写了fnm env。另外有些终端模拟器可能不会在启动时加载 PowerShell profile比如某些 IDE 内置终端带了-NoProfile参数这种情况需要单独处理后面 IDE 部分会讲。4.4 全局 npm 包和版本之间的取舍Node 换版本很多人马上会问我项目里用的 pnpm、yarn 会不会丢全局装的 CLI 工具会不会没掉先说结论fnm 本身不会清理你的全局包。但全局包能不能在下一个 Node 版本里继续用取决于它是安装在系统公用路径还是安装在当前 Node 版本自己的目录里。你可以先看下 npm 当前全局前缀npm config get prefixWindows 上常见的输出有C:\Users\你\AppData\Roaming\npm也有可能是某个具体的 Node 版本目录。如果是前者那大多数终端工具的命令入口在这个目录里切换 Node 版本后依然能访问如果是后者那切版本之后新版本里可能看不到之前全局装的工具。我的建议很简单全局工具只装构建类的、跟项目运行时无关的比如 pnpm、yarn、terser 之类的。真正的项目依赖一定装进项目自己的 node_modules不要图省事全局装。至于每个 Node 版本要不要隔离全局包我倾向于随缘。如果你经常需要在不同 Node 版本下测试同一个全局工具的行为可以给每个版本单独设置 npm prefix如果你只是日常开发就让全局包放在稳定的公共目录里省心。4.5 配合 corepack 用 pnpm / yarnfnm 管理的每个 Node 版本自带了 npm也带了 corepack。corepack 是 Node 官方提供的包管理器加载器可以按项目声明的包管理器版本自动启用 pnpm 或 yarn。在 Node 版本目录里先启用corepack enable然后在项目根目录的 package.json 里声明{ packageManager: pnpm9.12.0 }之后在这个项目里执行 pnpm 命令时corepack 会按照声明调用对应版本。这样你就不用关心全局装没装 pnpm只要 Node 版本里有 corepack就能跑起来。有一点要注意corepack 是跟 Node 版本走的。如果你用 fnm 切到另一个 Node 版本那个版本的 corepack 可能还没有启用 pnpm需要在那个版本下重新corepack enable或者直接用项目里的corepack prepare pnpmlatest --activate激活一次。5. VS Code 和 JetBrains 里让 fnm 生效的配置细节5.1 VS Code 终端识别不到 fnm 的排障链路很多人在操作系统终端里已经用得好好的结果打开 VS Code打开内置终端一运行fnm就提示找不到命令。这里最常见的原因有五个。第一个是 VS Code 内置终端继承的环境变量里没有 fnm 的安装目录。VS Code 一般是在图形界面里启动的Windows 不会重新读取用户环境变量。你确认一下系统环境变量是在安装 fnm 之后才加的吗如果是关掉全部 VS Code 窗口再重新打开。一个可行的验证方式是重启电脑之后再看因为 Windows 资源管理器及其子进程会缓存环境变量单纯重开 VS Code 不一定能刷新。第二个是 VS Code 内置终端用的不一定是你平时用的 PowerShell profile。VS Code 的默认终端配置可以单独指定如果它使用了commandline参数并带了-NoProfile那 profile 里的 fnm 初始化就不会执行。去 VS Code 设置里搜 terminal integrated profiles看看默认 profile 是什么。第三个是 Windows 执行策略只在普通终端改了VS Code 以管理员权限运行时可能又切回了 Restricted。这个需要你确认自己 VS Code 是不是以管理员身份运行然后在管理员 PowerShell 下重新设置一下执行策略。第四个是你在打开 VS Code 之前当前 Shell 里的 PATH 已经被设置过里面有一个旧版 Node 的路径排在 fnm 前面。这种情况fnm current可能显示正常但node -v还是旧版本。解决方案下面统一说。第五个是 VS Code 扩展名 Remote-SSH、WSL 这类场景。这种场景下你在 Windows 上装的 fnm 只在本地 Windows 环境生效如果连到的是远程 Linux那需要在远程环境里另装一套 Node 版本管理工具。5.2 让 VS Code 内置终端继承 PowerShell profile如果你确认系统环境变量没问题只是 profile 没加载可以在 VS Code 的 settings.json 里指定使用系统的 PowerShell而不是用奇怪的参数包裹{ terminal.integrated.profiles.windows: { PowerShell: { source: PowerShell, args: [] } }, terminal.integrated.defaultProfile.windows: PowerShell }这样 VS Code 内置终端会使用你的 PowerShell profile。保存后重开终端再执行fnm current验证。如果还是不行可以打开 VS Code 的终端手动执行. $PROFILE这一句会把 profile 重新加载一遍。如果手动加载后 fnm 可用就说明配置文件本身没问题只是 VS Code 启动时没有加载 profile。5.3 JetBrains 系列 IDE 的终端环境怎么处理JetBrains 的 IDEA、WebStorm、PyCharm 等内置终端默认用的是系统 Shell一般来说只要你在 PowerShell profile 里配了 fnm打开 Terminal 面板就能直接用。但如果发现不行去Settings - Tools - Terminal把 Shell path 改成powershell.exe或者如果你用的是 PowerShell 7就改成pwsh.exe。然后在Shell arguments里不要额外写-NoProfile否则 profile 就不会执行。JetBrains 的 Terminal 面板还有一个特点它的环境变量是在 IDE 启动时缓存的。如果你在安装 fnm 之前打开过 IDE之后又改了 PATH大概率需要完全退出 IDE 再重启甚至可能需要注销一次才能让它识别到新的 fnm 目录。5.4 Windows Terminal 和普通终端Windows Terminal 本身只是终端外壳它支持的 Shell 也能正常读取 profile。升级到 Windows Terminal PowerShell 7 之后只要 profile 配置正确--use-on-cd的体验很顺滑。我自己的日常组合就是 Windows Terminal PowerShell 7 fnm。如果你用的是 Cmder 或 ConEmu核心其实是你把它们配置成了哪个 Shell。如果它们调用的是 PowerShell那 profile 同样生效如果调用的是 cmd就走前面说的 cmd 初始化逻辑。6. 报错排查那些我遇到过、也很多人踩过的坑6.1 error installing 24.20.0: node.js v24.20.0 is not yet released or is not available是怎么回事这个报错看起来很吓人其实多半不是 fnm 坏了而是你写了一个不存在的版本号。Node.js 版本号是精确的你在 fnm install 后面写 24.20.0fnm 会拿着这个完整版本号去 Node 官方发行目录查查不到就会提示 not yet released。解决办法有两条路。第一先看远程到底有哪些版本fnm ls-remote列表会很长你可以搜索一下fnm ls-remote | Select-String 24看到真实存在的版本后再安装。第二如果不是非要用精确版本直接用fnm install 24让 fnm 帮你解析到 24 这个大版本下的最新可用版本。也有人会遇到fnm ls-remote返回空列表的情况这个多半是网络问题或者某个 CDN 节点响应超时。重试几次一般能缓过来。6.2 装了版本但 node -v 还是旧版PATH 打架怎么处理这是 Windows 上最经典的 Node 版本管理问题。你明明fnm install 22 fnm use 22但一敲node -v还是原来的 18.20.0 之类的。第一步先看fnm current显示什么。如果 fnm 认为当前是 22但 node 不是说明 PATH 里存在别的 node.exe 入口位置排在 fnm 的临时目录前面。按下面顺序排查Get-Command node | Format-List Source如果你看到 Source 指向的不是FNM_DIR里的路径而是C:\Program Files\nodejs\node.exe或者C:\Users\xxx\AppData\Roaming\npm\node.exe那就说明旧 Node 入口还在。需要去环境变量里把旧 Node 的目录删掉或者把 fnm 临时目录往 PATH 前面挪。我自己踩过最隐蔽的坑是以前装 Node 官方安装包时它会在用户 PATH 里写入C:\Users\你\AppData\Roaming\npm而旧版本的 npm 全局目录里也放了一个 node.exe 的软连接或者副本结果这个目录优先级比 fnm 的临时目录高导致怎么切都没用。清理方法是去系统设置里打开环境变量编辑器把关于旧 Node 的两条路径都检查一遍包括用户变量和系统变量。删掉之后再重开终端Get-Command node的 Source 应该就指向 fnm 的临时目录了。注意不要在一个终端里同时运行多个版本管理工具比如 fnm 和 nvm-windows 混着用。否则两个工具的 PATH 修改会互相覆盖排查起来非常头大。6.3 自动切换失效进项目目录还是默认版本这个问题的第一嫌疑是你的 PowerShell profile 里写的是fnm env | Out-String | Invoke-Expression而不是fnm env --use-on-cd | Out-String | Invoke-Expression别小看--use-on-cd这个参数它决定了是否会注册目录改变时自动切换的行为。没有它fnm 只在终端启动时加载一次默认版本进入项目目录后不会自动 use。第二嫌疑是项目根目录没放.node-version或者放了但名字写错比如写成了.node_version。fnm 只认.node-version和.nvmrc其他类似命名的文件都不认。第三嫌疑是你当前所在目录层级太深而项目根目录的.node-version不在当前目录fnm 的自动切换大概率只在进入包含版本文件的目录时触发。如果你从/project/src里手动执行fnm use它也能切但不会因为你进入/project/src就自动去/project找。最好的做法是版本文件一定要放在项目根目录并且平时以项目根目录为工作目录来打开终端。6.4 删除版本时文件被占用Windows 专属问题fnm 卸载版本很简单fnm uninstall 16但 Windows 上经常遇到文件被占用的报错因为当前终端或某个后台进程还占着那个版本的 node.exe 或 npm.exe。最直接的办法是先把当前终端切到别的版本或者关掉所有使用 Node 的终端窗口再执行卸载。如果依然删不掉可以去FNM_DIR\node-versions下手动删除对应版本目录。删除之前确保没有进程在跑。可以用任务管理器搜一下有没有 node.exe 进程结束掉再删。这里也顺便说一下fnm 的版本目录里不会保存你的项目 node_modules所以删除某个 Node 版本不会影响项目里的依赖。项目重新切到这个版本时node_modules 依然在项目目录里只是可能需要重新编译原生模块。6.5 想彻底卸载 fnm 的时候要清理哪些东西如果你最终不想用 fnm 了别只删掉 fnm.exe。还要清理四样东西第一FNM_DIR目录默认在%APPDATA%\fnm里面存着所有 Node 版本第二环境变量里的FNM_DIR第三PATH 里加的 fnm 安装目录第四PowerShell profile 里的fnm env | Out-String | Invoke-Expression一行。如果不删 profile重开终端会提示找不到 fnm 命令。另外你之前用 fnm 安装的 Node 版本如果还想留着需要在卸载前找到版本目录把需要的文件备份出来。如果你是用 winget 装的可以winget uninstall Schniz.fnm如果是 Scoop 装的scoop uninstall fnm压缩包装的直接删目录即可。7. 一套我目前在用的 Windows fnm 配置参考文章最后我把自己现在用的这套 Windows 开发机配置思路整理一下算是给你一个可直接复制的参考而不是再讲一遍概念。我的方案是Windows Terminal PowerShell 7 winget 安装 fnm FNM_DIR 指到 D 盘。具体操作顺序是这样的先用 winget 装 fnm设置FNM_DIR到D:\Tools\fnm-data然后在 PowerShell 7 的 profile 里只写一行fnm env --use-on-cd | Out-String | Invoke-Expression执行一次Set-ExecutionPolicy RemoteSigned -Scope CurrentUser然后重启终端。接着安装 LTS 版本fnm install --lts fnm default 22最后在每个需要固定版本的项目根目录建一个.node-version写入精确版本号。这样我打开终端进入目录fnm 会自动切到正确版本打开 VS Code内置终端加载 PowerShell profile 后也同样能识别。如果某天遇到fnm current正常但node -v不对我会先跑一句Get-Command node | Format-List Source十有八九能定位到旧的 Node 路径。Windows 下 fnm 用起来并不复杂复杂的是系统和历史安装残留。只要你把 PATH 的优先级理解清楚大部分问题都能自己解决。