包管理
包管理工具
npm
npm的全称是Node Package Manager,是随同NodeJS一起安装的包管理和分发工具,它很方便让JavaScript开发者下载、安装、上传以及管理已经安装的包。其常用指令如下:
| npm命令 | 备注解释 |
|---|---|
| npm i <pkg> | 安装package包,等价于npm install <pkg> 默认安装package包的最新版本 |
| npm i <pkg> -g | 全局安装 |
| npm i <pkg> -dev | 安装到开发环境 |
| npm i <pkg> @version | 安装指定版本的包 |
| npm i <pkg> @version ">a <b" | 安装a~b之间的版本 |
| npm uninstall <pkg> | 卸载指定包 |
| npm update <pkg> | 更新指定包 |
| npm run 命令 | 运行package.json中指定的script脚本 |
| npm config set registry url | 设置指定的下载源 |
pnpm
使用npm时,依赖每次被不同的项目使用,都会重复安装一次。 而在使用 pnpm 时,依赖会被存储在内容可寻址的存储中(软链接和硬链接),所以:
- 如果用到了某依赖项的不同版本,只会将不同版本间有差异的文件添加到仓库。
例如,如果某个包有100个文件,而它的新版本只改变了其中1个文件。那么
pnpm update时只会向存储中心额外添加1个新文件,而不会因为仅仅一个文件的改变复制整新版本包的内容。
- 所有文件都会存储在硬盘上的某一位置。
当软件包被被安装时,包里的文件会硬链接到这一位置,而不会占用额外的磁盘空间。 允许
跨项目地共享同一版本的依赖。
因此,可在磁盘上节省大量空间,这与项目和依赖项的数量成正比,并且安装速度要快得多!
配置文件
package.json
用来描述项目以及项目所依赖的模块信息
生成
# 创建时填写信息
npm init
# 所有信息使用默认的
npm init -y常见配置说明
依赖集中的版本号,都是依据SemVer版本规范的
{
"name": "", // 项目名称
"version": "", // 项目版本
"private": "", // 是否私有
"description": "", // 项目描述
"author": "", // 作者
"license": "", // 开源协议
"main": "", // 设置程序入口
"script": {}, // 脚本命令
"dependencies": {
"vue": "*x.y.z", // *表示匹配 *.*.* 版本 其中*表示最新
"vue": "^x.y.z", // ^表示匹配 x.*.* 版本
"vue": "~x.y.z", // ~表示匹配 x.y.* 版本
"vue": "x.y.z", // 固定版本号为 x.y.z
}, // 依赖集
"devDependencies": {
"webpack": "版本号",
"babel": "版本号",
"loader": "版本号",
"...": "...",
}, // 开发依赖集
"peerDependencies": {
"vue3": "版本号", // 比如element-plus的对等依赖集-vue
"...": "...",
}, // 对等依赖集,依赖的这个包,它必须是以另外一个宿主为前提
"engines": {
"node": ">=16.14.0",
"pnpm": ">=3",
}
}lock文件
lock文件的作用是确保在不同机器上或在不同时间安装相同的依赖包时,获得相同的版本,以避免由于版本不一致而产生的问题。在安装依赖包时,lock文件会锁定当前的依赖树,并记录每个依赖包的确切版本号和依赖关系。这样,在重新安装依赖包时,将使用lock文件中记录的版本和依赖关系来安装依赖包,而不是根据package.json文件中的符号依赖去解析版本。这确保了依赖包版本的一致性。
相关知识点
npm install 的原理?

- 检查项目中有无 lock 文件
- 无lock文件
- 从npm远程仓库获取包信息
- 根据package.json构建依赖树,构建过程
- 构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 node_modules 根目录。
- 当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 node_modules 下放置该模块。
- 注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包
- 在缓存中依次查找依赖树中的每个包
- 存在缓存: 将缓存按照依赖结构解压到 node_modules
- 不存在缓存
- 从 npm 远程仓库下载包
- 校验包的完整性
- 校验不通过则重新下载包
- 校验通过
- 将下载的包复制到 npm 缓存目录
- 将下载的包按照依赖结构解压到 node_modules
- 将包解压到 node_modules
- 生成 lock 文件
- 有lock文件
- 检查 package.json 中的依赖版本是否和 package-lock.json 中的依赖有冲突。
- 如果没有冲突,直接跳过获取包信息、构建依赖树过程,开始在缓存中查找包信息,后续过程相同
- 无lock文件
为什么不直接在package.json中固定版本号,而是在lock文件中?
package.josn虽然可以固定版本号,但package.json中依赖库所依赖的库并不是按照固定版本号进行迭代的。一旦依赖库所依赖的库有所升级,在没有lock的情况下,就会被更新到最新。无法保证更新后的依赖对package.json中固定版本号的依赖仍然兼容。
一句话总结就是:需要保证多人开发时,依赖库的依赖库版本一致
@keyboarder-yang