fnm
fnm 是 Node.js 版本管理器。本页介绍 Windows、macOS 和 Linux 上的 shell 配置,以及 multishell 目录的清理。
配置#
以下两节按平台选用。
在 Windows 上配置#
在 PowerShell profile 里加载补全:
在 PowerShell profile 里加载 fnm 环境。fnm env 每次启动都要执行,它为当前会话创建 multishell 目录:
可选:设置 Node.js 和 corepack 的镜像源,运行一次即可:
在 macOS 和 Linux 上配置#
在 shell 配置文件(如 ~/.zshrc)里加上以下内容。
Homebrew 装的 fnm 存在时加载环境:
启用切换目录时自动切换版本等选项:
可选:设置 Node.js 和 corepack 的镜像源:
故障排查#
multishell 目录不断堆积#
fnm_multishells 下的条目数一直增长,目录数多了会拖慢遍历。
原因:每开一个 shell,fnm 都会建一个 multishell 目录,退出时不清理。
- Windows:位于
%LOCALAPPDATA%\fnm_multishells,是 junction,本身几乎不占空间。 - macOS:位于
~/.local/state/fnm_multishells,是符号链接,du -sh显示 0B。
解决:任选一种清理方式。
按创建时间清理(Windows)。删除一天前创建的目录:
按 PID 清理。目录名格式是 <PID>_<时间戳>,可以判断创建它的 shell 是否还在运行,不会误删当前开着的会话:
PID 可能被复用,最坏情况是漏删一个,不会误删活着的会话。
删 junction 不会影响目标,%APPDATA%\fnm\node-versions 下的 node 安装不受影响。
清理后长时间运行的进程里找不到 node#
按 PID 清理后,编辑器集成终端、agent 会话、tmux 或 herdr 的 pane 里,node 命令消失。
原因:子进程继承父进程的 PATH。创建 multishell 目录的 shell 已退出,但它的后代进程仍在运行并引用这个目录。
检查当前 PATH 里是否有已失效的 multishell 目录:
解决:
-
重启受影响的进程。新开的 shell 会重新生成自己的目录。
-
以后清理时同时满足两个条件才删除:进程已退出,且创建时间超过一天:
fnm_multishells 显示占用数 GB#
在 Windows 上统计 %LOCALAPPDATA%\fnm_multishells 的体积,结果有几个 GB。
原因:Get-ChildItem -Recurse 会穿透 junction,把同一份 node 安装重复计算很多次。实际并不占这么多空间。
解决:无需处理。按multishell 目录不断堆积清理条目即可。