npm和pnpm作为包管理工具
在应用中npm会下载所有声明的依赖包以及依赖包的依赖包,v5版本之后有做缓存的优化,pnpm 为了解决npm的性能和磁盘问题,使用符号链接和硬链接来处理依赖,利用全局内存,并且避免重复的下载
本文主要介绍软/硬链接的使用以及其作用
1、 Windows系统mklink创建链接
了解npm和pnpm创建软硬链接之前,我们先了解一下Windows系统通过mklink命令创建符号链接实现软/硬链接,
打开cmd命令行(注意不是power shell),输入mklink命令回车,可以看到mklink命令对应的使用方法,默认为/D创建软连接,/H用来创建硬链接,Link和Target参数都为必填项
1.1:/H创建硬链接
首先在源目标文件夹中创建文件index.js
之后定位到需要创建硬链接的F:/newlink/文件夹目录,并打开cmd命令行执行命令
mklink /H index1.js "../link/index.js"
PS:Target参数的值如果带有特殊符号(\ / : * ? ” < > |)需要用双引号包裹
执行之后可以看到命令行提示创建了文件F:\newlink\index.js与源目标文件F:\link\index.js之间的硬链接;同时F:\newlink\文件夹下生成了对应的index.js文件
建立硬链接之后两个文件有什么特性呢?改一下文件内容试一下,分别更改两个文件夹下的index.js文件能够看到两边的文件内容会保持一致并且同步更新,类似于文件副本,不同点在于同步更新
1.2:/D创建软链接
硬链接可以创建文件副本,并同步更新,那软链接又有什么特性,可以用来干什么
我们同样在newlink文件夹下通过命令行创建软链接
执行命令提示我们没有足够的权限,以管理员模式打开命令行重新执行创建命令
创建命令结果提示创建了符号链接,打开文件夹发现与创建硬链接不同,软链接创建生成文件大小为0kb,并且图标类似与快捷方式
2、硬链接和软连接在npm和pnpm中的应用
2.1:npm和npm link
npm做包管理具有扁平化的项目结构,会对声明的依赖以及依赖包的依赖进行完全的下载,所以会消耗更多的下载时间和内存资源;同时可能导致不同包之间依赖版本冲突的问题;
但是npm拥有用户基础、文档支持,没有什么使用壁垒,在项目中得到普遍使用;
而关于软链接在npm中的使用,在想要做npm包开发,特别是组件库、方法库等的开发调试时,往往需要依赖项目进行调试,我们不可能使用发布上线的形式进行包的调试,而npm link可以通过创建软链接的形式,实现本地开发包的调试(如果存在多项目引用场景可以使用Yalc工具,不做介绍),操作步骤:
1、在开发的包根目录执行 npm link(注意项目是否需要构建更新)
2、在使用或引用包的项目目录下执行 npm link 包名,这个时候你会发现项目中引用的包已经软链到本地文件
3、如果完成调试或者想要释放软连接可以执行 npm unlink
2.2:pnpm和monorepo
使用 pnpm (项目初衷 | pnpm中文文档 | pnpm中文网)时,依赖会被存储在内容可寻址的存储中,如果你用到了某依赖项的不同版本,只会将不同版本间有差异的文件添加到仓库。
所有文件都会存储在硬盘上的某一位置。 当软件包被被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间。 这允许你跨项目地共享同一版本的依赖。
在项目安装依赖时,会进行依赖解析,对已经安装的全局包直接软链接到项目中。
Monorepo 是一种项目开发与管理的策略模式,它代表"单一代码仓库"(Monolithic Repository)。在 Monorepo 模式中,所有相关的项目和组件都被存储在一个统一的代码仓库中,而不是分散在多个独立的代码仓库中,可以实现多项目管理,业务组件库、方法库在多项目中的使用,而不需要将其发布到npm(有其他使用场景欢迎补充)。
而基于pnpm进行monorepo仓库创建时,
1、多项目文件夹目录下pnpm init之后新建pnpm-workspace.yaml文件
2、声明配置pnpm-workspace.yaml文件
packages: # 项目1文件夹名 - 'project1' # 项目2文件夹名 - 'project2' # 组件库文件夹名 - 'components' # 方法库文件夹名 - 'utils'
3、在需要共享但是没有package.json的文件夹如components中执行pnpm init进行初始化,并且在index文件中抛出组件或方法
4、引用组件/方法
// 根据组件名直接从声明的仓库中引入 import { ComponentsName } from 'components'