为什么前端项目中要使用yarn.lock?
以下内容经过了脱敏处理
一、背景
下文中的“lock文件”指yarn.lock文件
1.在牛客的前端开发中,会使用到很多牛客自己发布或者fork其他人代码代码的npm包。这些包基于场景需要,在package.json中通过写死版本号锁定了依赖版本(错误行为,需要不锁死或使用lock文件)。
上图是牛客某次服务部署流水线报错的原因
但是这就造成了一个问题,虽然我们锁定了一个包的依赖版本。但是这个包的依赖,我们没办法锁定,所以当依赖的依赖不支持我们锁定的这个版本时,就会出现打包报错的问题。
2.不使用lock文件,每次安装依赖都使用规则允许的最新版本,代表我们相信包的作者发布的代码是可靠的,实际上是错误的。
二、解决方案
1.关于yarn.lock
下图是关于yarn.lock文件的官网介绍,其实也说明了我们以上遇到的问题的解决思路
大概翻译一下上述文档表达的内容
为了在机器上安装始终如一的依赖版本,yarn需要packjson之外的更多信息,为了解决这个问题,yarn引入了lockfiles文件。yarn的lockfiles和npm-shrinkwrap.json比较相似,他不会失真且可以重新生成。
- 被yarn管理
- 你的yarn.lock文件是被yarn指令自动全量生成的,当你通过yarn指令做 add/upgrade/remove操作时,他会自动更新yarn.lock文件。不要直接手动编辑这个文件,因为这样很容易产生错误和冲突。
- 只对应当前的package.json文件
- 在安装过程中,yarn只会使用最顶层的yarn.lock文件。最顶层的yarn.lock文件包含了你需要的依赖的所有的锁定的版本。
- 将yarn.lock提交到你的版本控制仓库中
- 所有的yarn.lock文件都应该被提交到代码仓库中(比如git或mercurial)。这样使yarn在所有的机器,不论是你同事的笔记本还是CI服务器上,都会安装完全相同的版本依赖。
- 框架和仓库也需要提交yarn.lock文件到版本控制仓库。不要担心他会对框架或库的使用者产生影响,因为使用者安装依赖时只会读取项目顶层的yarn.lock(而库或者框架的yarn.lock存在于node_modules/pkg/中)。
2.使用yarn.lock
1.yarn.lock应该只由一个项目负责人更新(这里的更新是指提交到git),所有人都更新的话将使这个文件失去部分意义。
2.不同于npm ci,在yarn中并不存在yarn ci这一指令,同时结合我们不希望普通的开发同学在开发中更新yarn.lock文件,结合yarn的使用说明,在业务中使用
rm -rf node_modules && yarn install --frozen-lockfile
组合指令模拟npm ci
为方便业务同学使用,将在项目的package.json中添加ci快捷指令
{
"private":"true",
"scripts":{
...,
"ci":"rm -rf node_modules && yarn install --frozen-lockfile "
}
} 3.注意的点,在我们的项目中,存在很多快捷脚本,如pack/dev.sh pack/build.sh pack/develop.sh pack/publish.sh等。要更新项目中这些shell脚本存在的yarn指令(添加了2中的快捷脚本后可以直接使用yarn ci)
3.收益
1.屏蔽掉业务逻辑之外的第三方发包对我们的影响,保证业务只要在生成yarn.lock时可构建,就一直可构建。
2.因为使用yarn.lock,所有的依赖版本都是确定的,安装过程中省去了包匹配环节,理论上会有2~5倍的依赖安装提速。
三、Q&A
非项目同学在开发feature时,需要更新某个包,需要通过yarn upgrade pkg@version进行升级,在提交merge request忽略yarn.lock文件,只提交package.json中的改动。在项目发版前,项目负责人删除yarn.lock,执行yarn进行重新安转和生成依赖(或者直接执行yarn --force
2.对于npm私有包的开发是否适应? 如果这个包准求的是稳定,那么是的,需要。同时第三方依赖的patch和minor版本可能会包含性能优化更新和bug修复(这些bug我们大概率遇不到),这一部分优势会放弃。
