🗒️fnm和corepack安装指南
2024-11-2
| 2025-2-12
Words 4216Read Time 11 min
URL
type
Post
status
Published
date
Nov 2, 2024
slug
summary
方便快捷的管理node版本和包管理器
tags
fnm
node
包管理器
npm
pnpm
yarn
corepack
category
笔记
icon
password
配置fnm和corepack时遇到了一些坑,记录下,包括网络问题和环境变量的配置。。。

一、为什么我们需要fnm和corepack?

fnm用于解决nodejs的版本管理问题。许多模块依赖于特定版本的nodejs,因此在一个系统里安装多个版本的nodejs就显得非常重要。fnm能让我们的系统中有多个版本的node共存,并且提供快捷的安装、切换、删除指定版本的命令。 相比于更知名的包管理工具nvm,fnm的特点是轻量、快速、跨平台,各种操作也都很直观易上手。这里有个fnm与其它node版本工具的性能对比,数据是2020年的。 fnm还可以劫持命令行的cd命令,用命令行进入某个文件夹时,自动检测当前目录下的.node-version文件或者.nvmrc文件,然后自动切换到对应的版本,没有这个版本会提示你下载。
corepack是管理包管理器的管理器,让我们不用担心在npm、pnpm和yarn中艰难选择。它会根据项目配置的指定版本包管理器,下载并缓存指定版本。当你在pnpm项目中使用npm,也会提示你使用正确的命令。你也可以很方便的在不同的包管理器版本中来回切换。

二、安装fnm

fnm github地址 直接根据fnm的官方文档安装,这里不多赘述:
  • mac和Linux提供了自动安装脚本。
  • Windows可以自行手动安装(注意,手动安装完成后记得配置shell,文档中有) 安装后命令行输入 fnm -V (大写V),如果返回版本号就是装上了。

2.1 常用命令(和nvm类似):

命令
作用
fnm list
列出已经安装的所有版本
fnm list-remote
列出可以下载的版本
fnm install [版本号]
安装指定版本,版本号可以从上一个命令中找到
fnm uninstall [版本号]
有安装就有卸载
fnm use [版本号]
切换到指定版本的node,版本号可以从fnm list中找到
fnm env [可选参数]
打印出当前fnm依赖的环境变量,可以配置一些fnm的扩展功能, 比如我们手动安装后,就是用它设置shell
fnm alias [版本号] [别名]
给已经安装的某个版本加个别名,毕竟版本号记不住, 加了后就可以 fnm use [别名] 来切换版本了
fnm current
忘了当前是哪个版本?用这个命令可以查看
[!WARNING] 注意! fnm似乎识别中文或特殊字符路径有问题,如果你的npm安装路径中有特殊字符,可能在用fnm use命令切换版本时报错。报错首先排查路径是否有特殊字符或中文,修改npm路径后,一定记得同时修改环境变量

2.2 fnm如何识别当前项目的nodejs版本?

第一种方式,通过读取项目目录下的.node-version.nvmrc文件来获取当前项目的node版本,所以你可以在自己的项目下创建这个文件来约束团队的node版本。 第二种方式,当开启fnm的解析引擎后,fnm就可以读取package.json中 "engines": {"node": ">=20 <21" } 这样的字段,获取到node版本。要开启解析引擎,可以看下面fnm env的用法。

2.3 fnm env的妙用

fnm env 命令后面跟上不同的参数能够修改对应的环境变量,开启不同的扩展功能。直接输入fnm env只能查看,是不会实际起作用的,要想实际起作用,得进行一些配置,可以先看后面的环境变量配置再回来看这里。
这里介绍几个官方推荐的配置: fnm env --use-on-cd :当你cd进入某个项目目录后,fnm会自动检测该项目的版本,然后提示你切换到对应的版本,或下载对应版本。还记得手动安装fnm后,让你配置shell时用的语句吗?那里面就默认添加了这个参数。 fnm env --version-file-strategy=recursive :配置了这个,当我们直接 fnm usefnm install 但不加任何参数,fnm就会去父文件夹中找版本文件(.node-version和.nvmrc)。 fnm env --corepack-enabled :新安装一个nodejs版本时,会自动运行corepack enable,也就是保证你新装的node默认开启corepack。 fnm env --resolve-engines :如上一节所说,开启这个后能够通过package.json中的engines字段来获取版本信息。如下:
[!WARNING] 注意! fnm切换node版本,必须要读取环境变量,否则会报错!因此一定要在终端中设置环境变量。后文的环境变量部分会介绍如何自动对环境变量进行设置。

三、安装corepack

corepack github地址 corepack是nodejs官方出品。如果用的新版nodejs,那么corepack是自带的,但默认关闭,你可以启用它:
手动安装corepack可以用如下命令,再启用:
安装或启用后,命令行运行corepack -v ,返回版本号就是装上了。

3.1 corepack基本使用

corepack打开就生效了,可以直接使用,以下是官方给出的基础能力:
只需像往常一样使用你的包管理器。在 Yarn 项目中运行yarn install,在 pnpm 项目中运行pnpm install,在 npm 项目中运行npm。Corepack 会捕捉这些调用,并根据情况进行相应处理:
  • 如果本地项目已为所使用的包管理器进行了配置,Corepack 将下载并缓存最新兼容版本。
  • 如果本地项目配置了不同的包管理器,Corepack 将提示您使用正确的包管理器重新运行命令,从而避免安装文件损坏。
  • 如果本地项目未配置任何包管理器,Corepack 将假定您知道自己在做什么,并使用已固定为“已知良好版本”的包管理器版本。查看相关部分了解更多详情。
为项目指定包管理器:在package.json中设置 "packageManager"字段,然后写上指定包管理器,示例如下:
上面设置的字符串包含包管理器名称、版本和用于验证的哈希值。
corepack的环境变量: corepack也有许多的环境变量,这些环境变量配置corepack的下载仓库地址、指定包管理器的位置、设置代理地址等等。详细可以看文档:corepack环境变量
更多功能和实用命令可以直接看github的文档。

四、环境变量设置

fnm和corepack都会通过读取环境变量来配置一些功能。而不同的环境下设置环境变量的方式不同,我们可以参考fnm配置shell的部分一窥究竟。

4.1 环境变量分类

环境变量就是一些供程序读取的值,通常是一个键值对,比如 KEY=value,主要有临时的持久化的两种环境变量。 临时环境变量: 通常是在打开的终端中设置的,终端关闭后就销毁了,并且只能这个终端读取,其它终端无法访问。 持久化的环境变量: 是存在系统的文件里面的,只要你不主动删除,随时都能读取,每个终端都能读取。而持久化的环境变量,分为用户级别系统级别。我们知道现代操作系统都支持多用户,因此用户级别的环境变量只能指定用户访问,而系统级别的每个用户都能访问。 在不同的系统和不同的终端程序中,设置环境变量的方法各不相同。

4.2 Linux/Mac

临时环境变量设置: 通过export进行设置,当前终端会话关闭后,这些环境变量也没了。
持久化环境变量: Linux和Mac系统有个启动脚本文件,每次打开终端,就会先执行这个文件中的命令。因此可以使用 echo xxx >> 启动脚本文件 把设置临时环境变量的命令写入这个脚本中,相当于每次打开终端都设置下这些环境变量。
不同的系统下有不同的启动脚本文件,用户级和系统级也分不同的启动脚本文件,可以自行查阅或问ai。

4.3 Windows

Windows下有好几个终端,每个终端都有自己配置环境变量的命令。
临时环境变量设置:* 在powershell中,使用 $env 来设置和查看环境变量,powershell关闭后,改命令创建的环境变量就销毁了。
在CMD和Cmder中,使用 set 来设置和查看环境变量,同样,也是临时的。
持久化环境变量设置: Windows设置持久化的环境变量有两种方式:
第一种(fnm和corepack不推荐):是经典的环境变量窗口设置,直接win键按出菜单搜索“环境变量”,大家根据图中路径打开窗口。可以看到这里有两块区域,分别对应用户级和系统级的环境变量。直接新建并输入变量名和值即可。 但是这里的环境变量通常是一些常用生产程序的路径,我们将fnm、corepack或者其他一些程序的环境变量放这里,会很显得很杂乱,不好管理,因此推荐下面的类似Linux/Mac的方式
notion image
第二种(推荐):在Windows中创建一个类似Linux中的启动脚本文件,当终端一打开,就自动设置临时环境变量,也相当于持久化了。powershell、cmd、cmder设置各有不同,下面一一来看。
powershell:powershell的配置简单,直接终端输入命令notepad $profile 会用记事本打开一个C:\Users\UserName\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 文件。你可以在里面写入命令,一行一个命令,打开powershell前,回先依次执行这些命令。
cmder:cmder的启动脚本文件在%CMDER_ROOT%\config\user_profile.cmd %CMDER也是个环境变量,记录了一个路径,可以在环境变量设置窗口中找到。
配置cmd太麻烦了,如果不是非要用cmd,建议只配置powershell吧。 cmd(系统级):我们得先修改注册表(为什么要改注册表?)。注册表和环境变量很类似,也是一些键值对,供程序读取使用,这里不展开赘述。搜索"注册表编辑器",并进入图中位置。空白处右击,新建一个字符串值。然后填入 值名称:AutoRun,数值数据:xxx/xxx/xxx.cmd 这里的值数据填一个路径,指向一个.bat结尾的文件。然后你在这个位置创建这个.bat文件,这就是cmd的启动脚本文件,你可以在里面写命令,每次打开cmd都会执行。
notion image
上述方式会作用到整个系统,也就是所有用户打开cmd都会尝试执行这个脚本(如果脚本文件不存在可能报错,未验证)。
cdm(用户级):要想设置到用户级,我们可以到下图所示的注册表路径,也就是HKEY_CURRENT_USER下面,一看名字就和用户有关。路径和系统级的配置差不多,但是,你会发现Microsoft下没有Command Processor?没事,可以自己创建一个,右击Microsoft文件夹(这个文件夹一样的东西在注册表里叫“项”)。然后把新项重命名为Command Processor。之后的操作就和上面一样了,添加AutoRun键值对,建立启动脚本文件,写入命令。
notion image

4.4 再探 fnm env

有了环境变量相关的知识,我们就能完全理解fnm env工作过程了。
由于我用的Windows系统,所以我们使用powershell和cmd各自运行fnm env命令,结果如下: powershell结果如下:
cmd结果如下:
我们可以发现,这不就是powershell和cmd各自用来设置环境变量的命令嘛! 我们还可以发现,同样一句fnm env ,fnm根据不同的终端,输出了与之对应的命令!
但是,这些命令被输出到终端里了,并没有真正的执行,比如我们想fnm每次下载node后开启corepack,输入 fnm env --corepack-enabled ,可以看到powershell输出下列内容:
notion image
这里相关环境变量显示未true,但是当我们输入 $env: FNM_COREPACK_ENABLED 后,发现这个值还是默认的false。
因此,fnm env 的真正作用,只是输出这些设置环境变量的命令的字符串,但是得靠我们自己来执行
notion image
再回头看看fnm文档中配置shell的部分,我们可以学习到,如何执行这些命令:
notion image
notion image
Linux中可以使用eval "$()" 命令,将fnm env输出的字符串替换掉$(),这样就可以用eval来执行这些命令了,--shell bash 参数,又保证了输出的是针对bash的命令。 powershell中同理,也是利用终端本身执行字符串数据的能力,通过管道操作,把fnm输出的流用Out-String处理为字符串,再用管道输送给Invoke-Expression,Invoke-Expression就能执行这些命令。 把这些命令写入启动脚本文件,就完成了启动终端立马进行环境变量初始化的操作。

4.5 corepack的环境变量

corepack没有给出设置环境变量的命令,因此我们直接在启动脚本文件中设置对应的环境变量即可,按着文档来。

五、疑难杂症

5.1 网络问题

我们使用fnm下载node或者使用corepack下载包管理器,可能会出现timeout超时错误,排除自身网络原因,最大的可能就是与海外链接不畅。
如果你是魔法师,请配置代理: fnm: fnm直接使用系统代理,读取系统代理的环境变量,大家可以自行查阅相关环境变量:
corepack: corepack的代理通过node-proxy-agent支持,涉及下列环境变量:HTTP_PROXYHTTPS_PROXY, and NO_PROXY
如果你是麻瓜,可以将下载源改为国内的镜像源fnm: 使用 fnm env --node-dist-mirror 镜像源地址 可以获取换源的命令。当然也可以直接设置FNM_NODE_DIST_MIRROR 环境变量,它的默认值是https://nodejs.org/dist。反正你已经知道环境变量怎么配了,哪种方法都可以。 corepack: corepack的下载源地址用环境变量COREPACK_NPM_REGISTRY来配置。默认是https://registry.npmjs.org

5.2 corepack下载的包管理器在哪里?

默认在:C:\Users\username\AppData\Local\node\corepack\v1
notion image
长期收录中。。。
  • fnm
  • node
  • 包管理器
  • npm
  • pnpm
  • yarn
  • corepack
  • JS数据拷贝简史每周学习总结03
    Loading...