背景
近期经常遇到包版本导致的问题,之前使用过 package-lock.json
来约束版本,但总是导致一些问题或者冲突,没有多研究原因,直接在 .gitignore
把它忽略了,当时倒是没啥问题,随着一些依赖包的更新,问题出现了。。
项目中 package.json
使用了框架默认的,包版本规则基本都是^开头,所以每次 npm install
都会根据版本规则安装最新的包,不可避免出现依赖包兼容问题。
忽略lock文件会导致包自动更新问题,不忽略会导致冲突或者意外报错,怎么办?
语义化版本控制
版本号由三部分组成:主版本号
、次版本号
、补丁版本号
。变更不同的版本号,代表不同的意义
- 主版本号(major):新的架构调整,不兼容老版本
- 次版本号(minor):新增功能,兼容老版本
- 补丁版本号(patch):修复bug,兼容老版本
"dependencies": {
"signale": "1.4.0", // 固定版本号
"figlet": "*", // 任意版本(>=0.0.0)
// 匹配主要版本(>=16.0.0 <17.0.0) 两种写法效果一样
"react": "16.x",
"react": "^16.3.0",
// 匹配主要版本和次要版本(>=16.3.0 <16.4.0) 两种写法效果一样
"react-dom": "16.3.x",
"react-dom": "^~16.3.0"
}
凡事都有意外,当主版本号为 0
的情况,会被认为是一个不稳定版本,情况与上面不同:
-
主版本号和次版本号都为
0
^0.0.z
、~0.0.z
都被当作固定版本,安装依赖时均不会发生变化。
-
主版本号为
0
-
^0.y.z
表现和~0.y.z
相同,只保持修订号为最新版本。
-
1.0.0 的版本号用于界定公共 API。当你的软件发布到了正式环境,或者有稳定的API时,就可以发布1.0.0版本了。所以,当你决定对外部发布一个正式版本的npm包时,把它的版本标为1.0.0。
package-lock.json
由来
为了解决 npm install
安装包版本的不确定性,从npm5.0.0开始,使用 npm install
会自动创建一个package-lock.json文件,而且文件比较大,单位为KB/MB,保存了 package.json
的依赖项,和 node_modules
一一对应,用于锁定包的具体来源和版本号,以保证其他伙伴安装时依赖能保持一致,下图就是部分对应关系的展示。
属性说明
- version 这个包当前安装在
node_modules
中的版本 - resolved 安装来源
- integrity 包
hash
值,基于Subresource Integrity
来验证已安装的软件包是否被改动过、是否已失效 - requires 子依赖的依赖,与子依赖的
package.json
中dependencies
的依赖项相同 - dependencies 是一个对象,对象和
node_modules
中的包结构一一对应
不同版本的区别
5.0.x 增加了版本锁定,每次 npm install
完全依赖 package-lock.json
文件安装,**即使修改了package.json,也不安装新的依赖。**so 新的问题出现了,如果我就是要更新呢,无解。删了 package-lock.json
,重新安装,这样就失去了lock的意义。
5.1.0 之后的版本,修改 package.json
会更新 package-lock.json
。执行 npm install
,如果有依赖更新,也会更新到 package-lock.json
5.7.0 之后 新增了ci命令 npm ci
会根据 package-lock.json
安装包
node版本与npm版本
node自带npm,虽然可以升级,但是一般都使用了自带的,对应的版本关系了解一下
npm install 常见问题
遇到一些安装报错等问题,通常搜索到几个命令,使用后解决就没有再关注,后续又遇到了类似问题。。
不同node版本安装的,运行报错
比如node8.0安装的包,切到node10.0运行提示版本问题,要么切换node版本,要么删除node_modules重装
报错 integrity checksum failed when using sha512: wanted sha512 xxx
通常删除 package-lock.json
重装,或者使用cnpm(lock文件对cnpm无效)
这样就破坏了锁定版本的目的,安装了版本不确定的依赖包,先看下为什么会报错
从上面两个图可以明显看出,就是因为sha512不一致导致的错误
解决方案:为了不影响 package-lock.json
锁定其他包的版本,先使用npm install element@version -S
单独安装这个包,这时 package-lock.json
也会更新,再执行 npm ci
安装其他依赖包
手动更新 package.json 却安装了非指定版本
比如把"umi": "^3.0.10"
手动改为"umi": "^3.0.11"
,结果实际安装了当前小版本最新的 3.2.27
,因为修改后的语义就是要安装 4.0.0
以下的版本,除非改为 "umi": "3.0.11"
才会安装指定版本
有 package-lock.json 文件 使用 npm install 为啥更新了 package-lock.json 文件
5.1.x之后的版本是这样,npm install
总是先检查是否有依赖更新,有的话,安装更新,写入 package-lock.json
。
即使你的项目直接固定了版本,但是依赖的依赖无法固定,还是会出现这种现象。
如果只想使用 package-lock.json
来安装且不更新依赖,npm使用5.7.1以上版本,使用 npm ci
结论
-
不建议忽略和删除操作
-
npm 建议使用5.7.1以上版本
-
安装包习惯从npm install 改为 npm ci
- 需要lock文件 没有
package-lock.json
会报错
- 需要lock文件 没有
-
更新包再使用npm install packageName
参考资料
- npm install docs.npmjs.com/cli/v6/comm…
- npm install实现原理 www.zhihu.com/question/66…
- npm ci www.npmjs.cn/cli/ci/
- 你不知道的npm zhuanlan.zhihu.com/p/102546577
- 剖析npm包的管理机制 blog.csdn.net/azl39798585…
- npm模块安装机制 www.ruanyifeng.com/blog/2016/0…
- 关于忽略package-lock的讨论 github.com/npm/npm/iss…