再見(jiàn) nvm,改用 fnm 了

配圖源自 Freepik

原文鏈接

社區(qū)上用于管理 Node 版本的工具很多,較為流行的有:

  • 非跨平臺(tái):nvm、n
  • 跨平臺(tái):nvs、fnm

個(gè)人棄用 nvm 不是因?yàn)樗豢缙脚_(tái),而是啟動(dòng) Shell 進(jìn)程太耗時(shí)了... 加之它本身問(wèn)題挺多的,詳見(jiàn):Important Notes。

對(duì)我最直接的影響是:此前那個(gè) 8G 運(yùn)存的 MacBook Pro 打開(kāi) VS Code 的時(shí)候,總會(huì)因?yàn)?Shell 解析太久導(dǎo)致 VS Code 終止解析,最終造成了某些 Plugins(比如 Mercurial 相關(guān)插件)無(wú)法正常使用。此前吐槽過(guò)了,可移步文章:解決 Unable to resolve your shell environment in a reasonable time。

一、fnm 安裝與使用

fnm(Fast Node Manager)基于 Rust 開(kāi)發(fā),是不是還沒(méi)用就感覺(jué)到它的快了,哈哈~
同時(shí),它是跨平臺(tái)的,支持 macOS、Linux、Windows。

?? Fast and simple Node.js version manager, built in Rust.

1. 安裝 fnm(以 macOS 為例)

$ brew install fnm

2. 配置 fnm 所需的環(huán)境變量到 bash 或 zsh 配置文件中,以 zsh 為例:

$ fnm env --use-on-cd >> ~/.zshrc

亦可執(zhí)行 fnm env --use-on-cd,將輸出內(nèi)容手動(dòng)添加至 .bash_profile.zshrc 里。

3. 用 fnm 安裝 Node

# 安裝 LTS 版本
$ fnm install --lts

# 安裝指定大版本的最新版本
$ fnm install 18

# 安裝指定版本
$ fnm install 18.21.1

相反地,可通過(guò) fnm uninstall <version>fnm uninstall <alias-name> 來(lái)刪除指定版本,后者會(huì)同時(shí)移除別名。

4. 通過(guò) fnm 來(lái)指定 Node 版本

# 使用系統(tǒng)版本
$ fnm use system

# 使用 fnm 所安裝,且版本號(hào)為 18.21.1 的 Node 程序
$ fnm use 18.21.1

# 使用 fnm 所安裝,且主版本號(hào)為 18 的最新版本的 Node 程序
$ fnm use 18

只要用 fnm use <version> 指定后,每次啟動(dòng) Shell 將會(huì)默認(rèn)使用對(duì)應(yīng)的 Node 版本。

5. 設(shè)置別名

# 形式如:fnm alias <指定版本號(hào)> <別名>
$ fnm alias 18.21.1 v18

# 設(shè)置別名后,可以簡(jiǎn)化指令為:
$ fnm use v18

其實(shí)以上示例的別名意義不大,僅用于舉例而已。原因是:在「不設(shè)置別名」的情況下,使用 fnm use 18,也能切換至 18.21.1。使用 fnm use <major> 會(huì)切換至對(duì)應(yīng)主版本號(hào)對(duì)應(yīng)的最新版本。

假設(shè)我們安裝了 18.20.018.21.1 兩個(gè)主版本號(hào)相同的 Node 程序,使用 fnm use 18 只會(huì)切換至 18.21.1(即最新的版本),盡管通過(guò) fnm alias 18.20.0 1818.20.0 的別名設(shè)為 18,這樣設(shè)置別名是無(wú)意義的。
此時(shí)可能需要用 fnm use 18.20fnm use 18.20.0 來(lái)切換指定版本了,或者其他非純數(shù)字的別名了。

較有意義的特殊別名 systemdefault

  • 前者是以 .pkg 等形式(比如官網(wǎng)下載的安裝包)所安裝的 Node 應(yīng)用程序,稱(chēng)為系統(tǒng)版本。
  • 后者是用于指定 fnm 的一個(gè)默認(rèn)版本,作為與 18 是類(lèi)似的,只是其語(yǔ)義表示默認(rèn)罷了。
# 指定默認(rèn)版本
$ fnm default 18.21.1

# 相當(dāng)于
$ fnm alias 18.21.1 default

相反地,可通過(guò) fnm unalias <alias-name> 來(lái)取消別名。

6. 項(xiàng)目中指定特定版本

可以通過(guò)在項(xiàng)目根目錄下添加 .node-version.nvmrc 文件,并在其中指定版本。比如:

$ echo '18' > .node-version

前提是,配置 fnm 環(huán)境用的是 fnm env --use-on-cd 命令,而不是 fnm env。后者沒(méi)有添加 Hook,因此不會(huì)是檢查對(duì)應(yīng)配置文件。有興趣的可以對(duì)比兩條命令的差別就明白了。

由于團(tuán)隊(duì)成員所安裝的 Node,其次版本或補(bǔ)丁版本號(hào)可能是不一樣的,因此,多數(shù)情況下指定主版本號(hào)即可,無(wú)需指定到 18.21.1 等更具體的版本號(hào)(特殊場(chǎng)景除外)。

7. 卸載 fnm

若是通過(guò) brew 安裝的 fnm,則:

$ brew uninstall fnm

接著,再移除 ~/.fnm 目錄。

$ rm -rf ~/.fnm

最后,移除 bashzsh 的配置文件中與 fnm 相關(guān)的配置。比如:

export PATH="/Users/frankie/Library/Caches/fnm_multishells/49559_1670052262156/bin":$PATH
export FNM_VERSION_FILE_STRATEGY="local"
export FNM_DIR="/Users/frankie/Library/Application Support/fnm"
export FNM_NODE_DIST_MIRROR="https://nodejs.org/dist"
export FNM_MULTISHELL_PATH="/Users/frankie/Library/Caches/fnm_multishells/49559_1670052262156"
export FNM_ARCH="x64"
export FNM_LOGLEVEL="info"
autoload -U add-zsh-hook
_fnm_autoload_hook() {
  if [[ -f .node-version || -f .nvmrc ]]; then
    fnm use --silent-if-unchanged
  fi
}

add-zsh-hook chpwd _fnm_autoload_hook &&
  _fnm_autoload_hook

rehash

二、移除 nvm

在移除之前,通過(guò)以下方式查看使用 nvm 所安裝的全局包,然后切換到 fnm 安裝一下(有需要的話(huà)):

$ nvm use 16
Now using node v16.14.0 (npm v8.3.1)

$ npm list -g
/Users/frankie/.nvm/versions/node/v16.14.0/lib
├── corepack@0.10.0
├── npm@8.3.1
├── pnpm@7.5.0
├── simple-shell@
└── zx@7.0.7

移除 nvm 的安裝目錄,通常是 ~/.nvm。執(zhí)行以下命令即可:

$ rm -rf "$NVM_DIR"

移除 bashzsh 的配置文件中與 nvm 相關(guān)的配置。比如:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use          # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion

其他系統(tǒng)可看 Uninstalling / Removal。

其他

相關(guān)內(nèi)容文章:

The end.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容