尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

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

Windows上Node多版本管理最佳实践:Fnm安装配置与使用指南 很多做前端和Node.js开发的朋友在Windows上折腾Node版本时应该都有过这种体验项目A要Node 14项目B要Node 18全局装了吧切版本就得手动下载安装包环境变量改来改去改完还得重开终端一不小心还会把系统搞乱。后来出现了nvm-windows确实方便了不少但用起来总感觉有点笨重切换速度也不够快有时候装着装着还报错。我自己也是被这个问题折磨了挺久后来换到了FnmFast 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它是按 nvmLinux/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 fnmscoop 的优点是它会帮你把 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.exe的Path变量另一个是指定「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存放你定义的版本别名比如default、lts-latestshims存放接管系统命令的 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 18fnm default 18设置全局默认 Node 版本新终端默认用这个fnm current查看当前终端使用的 Node 版本fnm uninstall 18卸载 Node 18fnm 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 --using18 npm install -g yarn在指定版本下安装全局包。顺带提一个很多人问的问题切换 Node 版本后npm会自动跟随吗答案是会。Fnm 管理的是整个 Node 发行版而 npm 随 Node 附带所以切换 Node 版本后npm也会自动变成那个版本对应的 npm。这在 Windows 上非常重要因为 npm 版本差异较大时package-lock.json的处理逻辑会有细微差异切换版本能避免很多莫名其妙的 lock 文件冲突。5.1 使用 .nvmrc 实现项目级版本锁定这是 Fnm 最让我喜欢的功能之一。和 nvmLinux/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 --using16 npm install这样会临时用 Node 16 执行npm install而不会动你终端的默认版本。这个命令特别适合给老项目打补丁、或者验证某个包在不同 Node 版本下的兼容性。6. 常见问题排查与避坑指南这里必须分享一些我实际踩坑总结出来的经验没有这些你按照教程操作一遍可能还是会遇到各种意外。这些问题如果不提前了解可能会卡你半小时甚至一下午。6.1 打开新终端提示fnm 不是内部或外部命令这是 Path 环境变量没配好或者终端没有重新打开导致的环境变量缓存问题。解决步骤先确认fnm.exe所在目录确实在 Path 里打开“编辑账户的环境变量”检查。确认后新开一个终端窗口不是新开标签页最好是完全退出终端程序再启动。如果还不行执行where fnm看系统能不能搜到。如果提示找不到说明 Path 里没有正确包含该目录再检查一遍路径是否写错。注意区分用户变量和系统变量。如果你把 Path 加在了系统变量里当前已经打开的终端软件包括 VS Code都需要完全重启才能读取到。6.2 fnm 能列出远程版本但 install 时特别慢或失败这在 Windows 上比较常见源于 Fnm 默认从 Node 官方源下载国内网络环境偶尔会不稳定。解决办法是配置镜像源。Fnm 支持通过环境变量FNM_NODE_DIST_MIRROR指定 Node 发行版镜像地址。在设置环境变量时新建一个用户变量FNM_NODE_DIST_MIRRORhttps://npmmirror.com/mirrors/node/这样再执行fnm install 20时就会从国内镜像下载速度快很多。这个镜像源是 npm 官方在国内的同步镜像长期可靠。6.3 切换版本后终端里的 node 还是旧版本这种情况一般发生在你配置了 Shell 集成但没有用fnm env初始化当前的 shell 会话。你敲fnm use 20Fnm 只是修改了当前会话的环境变量但如果 Shell 配置没有正确加载可能不会生效。解决方法是确认$PROFILE文件里已经有fnm env --use-on-cd | Out-String | Invoke-Expression然后重启终端。如果你不想改$PROFILE也可以用临时方案fnm env | Out-String | Invoke-Expression手动执行一次当前终端会立刻可用但新终端不会保留所以最终还是要配置$PROFILE。6.4 系统之前装过 Node.jsFnm 安装后 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 --depth0然后在 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. 我的最终推荐配置与几点心得体会最后分享一个我目前在用的推荐配置结构如果你完全照着做基本可以少走很多弯路用 winget 安装 Fnmwinget install Schniz.fnm设置用户环境变量FNM_DIR为D:\Tools\fnm_data记得用你自己的路径在 PowerShell 配置文件$PROFILE添加一行fnm env --use-on-cd | Out-String | Invoke-Expression设置默认 Node 版本fnm install --ltsfnm default lts-latest命令行工具推荐直接用 Windows Terminal 的 PowerShell 配置关闭后重开终端项目根目录统一维护.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 版本完全不受影响。
返回列表