【译作】第一期:yarn.lock和package-lock.json

hello,我是海海

这一期是关于锁文件的一篇译作。阅读时间6分钟

欢迎转载,请注明原文和作者

翻译的不够好,欢迎底部发消息帮我纠错

原标题:What is package lock json and how a lockfile works for yarn and npm packages?

原作者:Liran Tal


本文大纲:

  • 什么是锁文件?
  • 为什么需要锁文件?
  • 锁文件的工作原理?
  • 特殊锁文件:npm-shrinkwrap.json
  • package.json和锁文件不同时,会怎样?
  • 构建应用程序或者第三方库时,该如何处理锁文件?

什么是锁文件?

在本文中,我们主要讨论npm的锁文件package-lock.jsonYarn的锁文件yarn.lock。作为开发项目的依赖清单,它可以指定项目的依赖版本和依赖的依赖版本,从而构建整个依赖树。

当安装依赖时,锁文件会首先被引入到项目中。锁文件会计算项目的依赖关系树并将其保存,其中包括了每个依赖关系的元数据。

这些元数据包括:

  • version:包版本
  • integrity:防止篡改的完整性哈希
  • resolved:包源地址

为什么需要锁文件?

锁文件能够在被创建时确定项目的整个依赖关系树的所有版本。

如果没有包锁定文件,Yarnnpm等包管理器将在包的依赖项安装过程中实时解析包的最新版本,而不是最初用于特定包的版本,这可能会造成问题。

举个例子,如果一个项目依赖于包dummy-pkg:^1.0.0,那么在不同时间执行的两个单独的安装可能会检索不同版本的dummy-pkg。如果A用户安装时版本为1.0.0,然后该包在几分钟后发布新版本1.0.1,B用户此时安装的版本会是1.0.1,而不是1.0.0。

锁文件的工作原理?

大多数npm生态可以识别两种包锁定文件:

  • yarn.lock
  • package-lock.json

没有什么比一个好的流程图更能解释这两者的使用了。

上图中使用了npmpackage-lock.json,但可以在任何地方用yarn.lock代替。唯一的例外是npm客户端发布过程中不会自动忽略yarn.lock文件(会自动忽略package-lock.json) 。因此,除非在.npmignore文件中明确忽略,否则它将包含在打包的tarball中。但是,正如我们在插图左侧看到的那样,即使该包锁定文件作为包的一部分存在,它也不会供使用该库的最终用户使用。

Yarnnpm都不会考虑在node_modules包中的锁文件(原文是transient dependencies),它们会被包管理器完全忽略。只有根目录的下的锁文件才有效。

特殊锁文件:npm-shrinkwrap.json

存在一个特殊的锁文件,即使对于node_modules中包的锁文件的依赖关系也会考虑该文件。这个文件是npm-shrinkwrap.json

这个文件不仅像yarn.lockpackage-lock.json一样能够固定依赖关系树,而且在发包时会被提交而不会像package-lock.json被忽略。

更重要的是,用户在运行npm install安装某包时,版本的选择权被控制在npm-shrinkwrap.json而不是package-lock.json

此外,需要注意的是,yarnnpm对于npm-shrinkwrap.json的处理方式也是不同的:

  • npm始终会将npm-shrinkwrap.json中的依赖项放入包自己的node_modules文件夹中,and will not try to flatten it up the tree.(这里翻译不好,可能是不会将其放在项目的依赖树上)
  • yarn会忽略npm-shrinkwrap.json

npm-shrinkwrap.json的用处:

  • 允许库的维护人员确定并管理自己的库依赖项,以便发布已知版本。虽然需要仔细维护整个依赖树
  • 使用该文件时,源代码管理中不需要存在任何其他锁文件。
  • 著名的例子,比如hapijs

package.json和锁文件不同时,会怎样?

开发人员添加或删除依赖项,克隆项目时安装依赖时都会引入锁文件,这些都是常见的做法,但如果他们在package.json中进行更改并忘记提交相关的锁文件时,会发生什么情况?

当项目的package.json与其锁文件不同步时,npmyarn等包管理器将尝试协调差异并生成新的依赖目录(mainfest)。虽然这听上去像是一件好事,但如果在CI期间发生这种情况,实际上会引发问题。

如果锁文件和package.json不同,并且构建时成功,则意味着正在构建或测试的项目可以使用任何版本的依赖,这与我们使用包管理器的目的背道而驰。

因此,建议包管理器在安装依赖时使用锁定文件。例如:

yarn install --frozen-lock file
npm ci

构建应用程序或者第三方库时,该如何处理锁文件?

关于如何使用锁文件的观点各不相同,具体取决于该项目是主应用程序,还是一个工具库。

对于使用锁文件的应用程序已经达成共识,但是作为工具库的项目,却没有,为什么会这样?

但是,如果不适用锁文件,依赖关系仅仅在安装期间确定,且对于维护者和使用者可能会有所不同。

就我个人而言,我认为库项目和应用程序没有什么不同,都应该包含一个锁文件,以便团队成员协作和可重现的构建。

我建议使用两个不同的CI构建来解决这个问题:

  • 使用锁文件构建
  • 忽略锁文件,只在构建时确定依赖关系

这不仅可以实现重复构建,并保持依赖关系一致,同时使用户可以发现库的任何潜在问题。


感谢你的耐心阅读,如果觉得好的话,可以给我点个赞吗

创作不易,感谢你的支持!

创作不易,感谢你的支持!

本文使用 markdown.com.cn 排版

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYVDPBLf' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片