忽略package-lock.json?

4,301 阅读4分钟

背景

近期经常遇到包版本导致的问题,之前使用过 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.jsondependencies的依赖项相同
  • 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,虽然可以升级,但是一般都使用了自带的,对应的版本关系了解一下

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无效)

这样就破坏了锁定版本的目的,安装了版本不确定的依赖包,先看下为什么会报错

 package-lock.json 中的版本

2.7.14正确的sha521

从上面两个图可以明显看出,就是因为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 会报错
  • 更新包再使用npm install packageName

参考资料

  1. npm install docs.npmjs.com/cli/v6/comm…
  2. npm install实现原理 www.zhihu.com/question/66…
  3. npm ci www.npmjs.cn/cli/ci/
  4. 你不知道的npm zhuanlan.zhihu.com/p/102546577
  5. 剖析npm包的管理机制 blog.csdn.net/azl39798585…
  6. npm模块安装机制 www.ruanyifeng.com/blog/2016/0…
  7. 关于忽略package-lock的讨论 github.com/npm/npm/iss…