关于包管理工具的一些总结

164 阅读5分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

依赖版本管理

npm的包通常需要遵从semver版本规范:

semver版本规范是X.Y.Z:

  • X主版本号(major):当你做了不兼容的 API 修改(可能不兼容之前的版本)
  • Y次版本号(minor):当你做了向下兼容的功能性新增(新功能增加,但是兼容之前的版本)
  • Z修订号(patch):当你做了向下兼容的问题修正(没有新功能,修复了之前版本的bug)

我们这里解释一下 ^和~的区别:

  • x.y.z:表示一个明确的版本号
  • ^x.y.z:表示x是保持不变的,y和z永远安装最新的版本
  • ~x.y.z:表示x和y保持不变的,z永远安装最新的版本

上面这个总是记混淆,所以想了一个办法来记。^表示顶尖的,顶尖的人想法全部都是最新的。

npm install 原理

image.png 大致介绍一下他的流程

没有package-loack.json文件

  • 查看package.json文件中的依赖字段,来查看都需要安装哪些包,并构建依赖关系(因为有些库可以依赖其他库,而且多个库可能都会相互依赖,我们只需要下载一个就行。)
  • 然后就去registry仓库中下载npm压缩包,并将其保存在缓存文件中,并且将它压缩到node_modules文件夹中。
  • 并生成lock文件

package-loack.json文件

  • 检查lock文件该包的依赖,并进行比较,查看依赖的包是否发生改变。
  • 没有改变,我们再去看本地是否有缓存。(可以通过npm config get cache查看缓存地址, 可以通过npm cache clean清除本地缓存)
  • 找到缓存文件我们就将其解压到node_modules文件中。

package-lock.json文件描述解析

  • name:项目的名称;-
  • version:项目的版本; -
  • lockfileVersion:lock文件的版本;
  • requires:使用requires来跟踪模块的依赖关系(如果他不为true,那么它将不能通过requires来表示依赖关系)
  • dependencies:项目的依赖。当前项目依赖axios,但是axios依赖follow-redireactsaxios中的属性如下:
    • version表示实际安装的axios的版本。
    • resolved用来记录下载的地址,registry仓库中的位置。
    • requires/dependencies记录当前模块的依赖。
    • integrity用来从缓存中获取索引,再通过索引去获取压缩包文件。

我们在通过npm install安装项目依赖时,他会参考lock文件,如果把lock文件删除,那么他将会下载最新版本的包。

如何在npm发布自己的包

  • 首先需要注册一个npm账号。
  • 将项目开发完毕后,执行npm login命令。
  • 登录成功后,执行npm publish命令进行发布。

如果发布的时候抛出这个错误

403 403 Forbidden - PUT https://registry.npmjs.org/math_tools - Package name too similar to existing package math-tools; try renaming your package to '@coderhow/math_tools' and publishing with 'npm publish --access=public' instead

表示当前报名和以存在的报名太相似,需要修改包名,并且通过npm publish --access=public来发布。

如果登录时抛出这个错误

 403 403 Forbidden - PUT https://registry.npmmirror.com/-/user/org.couchdb.user:coderhow - [FORBIDDEN] Public registration is not allowed

表示当前你处于淘宝镜像,需要切换回npm本仓库地址

    npm config set registry https://registry.npmjs.org/

pnpm

首先先了解一下操作系统中的软连接和硬链接吧

软连接和硬链接

硬链接(英语:hard link)是电脑文件系统中的多个文件平等地共享同一个文件存储单元。删除一个文件名字后,还可以用其它名字继续访问该文件。

符号链接(软链接、Symbolic link)是一类特殊的文件。其包含有一条以绝对路径或者相对路径的形式指向其它文件或者目录的引用。其实就是电脑中的快捷方式。

image.png

软连接,硬链接实操

  • 文件的拷贝:文件的拷贝每个人都非常熟悉,会在硬盘中复制出来一份新的文件数据;
    // 对应的系统执行以下命令
    window: copy foo.js foo_copy.js 
    macos : cp foo.js foo_copy.js 

image.png

  • 文件的硬链接
    window: mklink /H aaa_hard.js aaa.js 
    macos : ln foo.js foo_hard.js 

image.png

  • 文件的软连接
    window: mklink aaa_soft.js aaa.js 
    macos : ln -s foo.js foo_copy.js

image.png

pnpm做了些啥

当使用 npm 或 Yarn 时,如果你有 100 个项目,并且所有项目都有一个相同的依赖包,那么, 你在硬盘上就需要保存 100 份该相同依赖包的副本。相当于是文件的拷贝。

如果是使用 pnpm,依赖包将被存放在一个统一的位置。(每个项目中的包通过硬链接获取

  • 如果你对同一依赖包使用相同的版本,那么磁盘上只有这个依赖包的一份文件;
  • 如果你对同一依赖包需要使用不同的版本,则仅有版本之间不同的文件会被存储起来;
  • 所有文件都保存在硬盘上的统一的位置(这个位置可以通过pnpm store path获取到,并建立硬链接): 当安装软件包时, 其包含的所有文件都会硬链接到此位置,而不会占用 额外的硬盘空间。这让你可以在项目之间方便地共享相同版本的依赖包。

pnpm构建的项目,node_modules是非扁平化的

node_modules中本身安装的包是硬连接到物理磁盘上的,但是其他依赖包是软连接到node_modules/.pnpm下的其他文件夹下的,依次循环。

image.png 这样的目的是可以避免,在我们项目非直接安装的包被项目使用。

管理本地存储的硬链接文件

随着我们的项目越来越多,下载的包也越来越多,以至于pnpm store path查找到的文件夹越来越大,占用的磁盘空间也越来越大,所以我们需要出定期删除那些我们不再使用的包。

执行下面命令pnpm store prune来删除。