Skip to content
文章摘要

优化前端npm包管理由yarn转pnpm

背景

以前使用npm或者yarn,你会发现一个项目目录下都要安装一个非常大的node_modules,里面有各种开发需要的包,占用空间还不小,每次安装也费劲,项目一多,磁盘空间都吃紧。

pnpm是一个快速的,节省磁盘空间的包管理工具,支持monorepos

不同的项目同一个依赖只会被安装一次,所有的依赖都会被安装到全局的目录,当软件包被被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间。 这允许你跨项目地共享同一版本的依赖。 安装的过程分三步:1. 依赖解析 2.目录计算 3. 链接依赖项

迁移前准备

全局安装pnpm

bash
npm install -g pnpm

如果已经安装,可以升级一下

bash
pnpm add -g pnpm to update

导入依赖

从另一个软件包管理器的 lock 文件生成 pnpm-lock.yaml。 支持的源文件:

  • package-lock.json
  • npm-shrinkwrap.json
  • yarn.lock

我的是yarn的,所以执行以下命令:

bash
pnpm import yarn.lock

安装依赖

bash
pnpm i

安装完成后,如果报错,某些包找不到,你可能还需要处理以下步骤,因为pnpm 默认创建了一个非平铺的 node_modules,因此代码无法访问任意包;但是我们的代码,以及我们依赖的第三方包中可能有直接引用了某些包。

你对比之前的node_modules 和pnpm安装的,你会发现结构都不一样。 yarn的所有npm包都平铺到node_modules目录,但是pnpm的只会把package.json里面显示的包放到node_modules最外层,其他的放到了.pnpm里面。

查看文档:https://pnpm.io/zh/npmrc

当 hoist 为 true 时,所有依赖项都会被提升到 node_modules/.pnpm/node_modules。 这使得 node_modules所有包都可以访问 未列出的依赖项。

添加配置文件.npmrc

在根目录下添加配置文件.npmrc,写入以下内容,具体配置参考pnpm官方文档;

  1. hoist-pattern
    • 默认值: ['*']
    • 类型: string[] 是告诉 pnpm 哪些包应该被提升到 node_modules/.pnpm/node_modules。 默认情况下,所有包都被提升 —— 但是,如果您知道只有某些有缺陷的包具有幻影依赖,您可以使用此选项专门提升幻影依赖(推荐做法)。
  2. public-hoist-pattern
    • 默认值: ['*']
    • 类型: string[] 不同于 hoist-pattern 会把依赖提升到一个虚拟存储中的隐藏的模块目录中,public-hoist-pattern 将匹配的依赖提升至根模块目录中。 提升至根模块目录中意味着应用代码可以访问到幻影依赖,即使他们对解析策略做了不当的修改。 当处理一些有缺陷的可插拔工具不能正确解析依赖关系时,此设置很有用。

根据自身情况添加,我是遇到了 @ant-design相关图标的包以及regenerator-runtime的包找不到

ini
auto-install-peers = true
hoist-pattern[] = *eslint*
hoist-pattern[] = *babel*
public-hoist-pattern[] = *@ant-design*
public-hoist-pattern[] = moment
public-hoist-pattern[] = regenerator-runtime

当然你也可以直接添加到package.json里面去安装到最外层,不过推荐的方式是配置的方式。

测试命令

pnpm serve 没有问题,pnpm build后也没问题,至此成功切换到pnpm。

何为硬链接

TIP

硬链接(Hard Link)是文件系统中的一种链接类型,它允许将一个文件与另一个文件关联在一起,使它们共享相同的物理数据块。在硬链接中,两个文件都指向同一个索引节点(Inode),并且在文件系统中没有区分链接和原始文件的概念。

硬链接的特点包括:

共享文件内容:硬链接创建了多个文件名指向相同的物理数据,因此修改其中一个文件将影响所有链接到该数据的文件。

目录中的链接计数:每个目录项都包含一个链接计数,用于记录链接到该文件的硬链接数。只有当所有链接都被删除时,文件的数据块才会真正释放。

不跨文件系统:硬链接只能在同一文件系统内创建,它们不能跨越不同的文件系统。

无法链接目录:由于硬链接是基于文件的,所以不能直接创建指向目录的硬链接。只能创建指向目录的符号链接(Symbolic Link)。

在使用硬链接时,删除原始文件不会影响硬链接的可用性,因为硬链接本身指向的是同一份数据。只有当所有硬链接都被删除时,文件的数据才会真正释放。

需要注意的是,硬链接不能跨越不同的文件系统,而且某些操作系统和文件系统可能对硬链接的数量有限制。此外,某些应用程序可能对硬链接的处理方式有所不同,因此在使用硬链接时需要注意文件的一致性和预期行为。