本文翻译自:https://robertcooper.me/post/how-yarn-lock-files-work-and-upgrading-dependencies
本文的目标就是解释清楚 yarn.lock 的作用,并且有 yarn.lock 文件在项目中时时如何升级依赖的。很多人看到这个文件就觉得很烦人,因为要添加额外的文件到项目中,而且只要修改了依赖它就会出现在 code review 里(有的时候文件 diff 可能会很多)。然而不管是个人开发还是团队合作 yarn.lock 都是非常重要的。
yarn.lock 文件是如何生效的?
我们使用 yarn 去管理 npm 包时,就会自动生成一个 yarn.lock 文件。而且不管是通过 yarn CLI命令行工具(比如 执行 yarn install
命令)添加、删除、修改依赖,yarn.lock 都会自动更新。
注意:如果我们手动的修改
package.json
文件里的依赖,yarn 只会在下次我们通过 yarn CLI 安装或者修改依赖时更新yarn.lock
。所以,如果我们修改了package.json
里的依赖,确保自己执行了yarn install
更新yarn.lock
文件。
yarn.lock
的作用就是用来锁住 package.json
文件里列出依赖的版本。这就意味着,yarn.lock 文件里有项目中使用的每个依赖及其子依赖的唯一标识。这里的唯一标识是指 yarn.lock
文件中有我们安装依赖的确切的版本的描述信息。这个描述信息,看起来,就像这样。
react@16.8.3: version "16.8.3" resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9" integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" scheduler "^0.13.3
在 yarn.lock
文件中,这段的意思就是
安装的 react 版本是 16.8.3
列出了这个依赖的注册地址(registry url)用于依赖包的安装
一串完整的 hash 码(用于确保依赖的文件没有被修改)
一系列的子依赖
那么,锁住依赖的版本有什么好处呢?如果没有锁住依赖,我们每次通过 yarn install
安装的依赖可能不一致。如果一个依赖有新的可用版本,并且这个版本是在 package.json
中依赖规定的范围内,就会把新的依赖给装上。
以下为例,在 package.json 中是这样写的。
"dependencies": { "lodash": "^3.9.1" }
假设当前 lodash 发布的版本是 3.9.1,当一个小伙子执行 yarn install, 那么会安装 3.9.1 版本的 lodash。
现在,假设 lodash 发布了版本 3.9.2,另一个小伙子用相同的 package.json 文件执行 yarn install,那么他安装的是 3.9.2 版本的 lodash,因为 3.9.2 在 package.json
规定的版本范围 ^3.9.1 内。这样这两个人即使代码一样但是下载的依赖版本却不一样。这可能导致相同 app 在不同机器上表现不一致。
接下来我们用 yarn.lock
再看一遍上面过程,看看有什么区别。
用上面相同的 package.json
为例,当前的 lodash 版本还是 3.9.1,当某个小伙子去安装依赖,会走 yarn.lock
。
lodash@^3.9.1: version "3.9.1" ...
现在,我们假设 yarn.lock
文件已经提交到了远程源码中(也是我们应该做的),另一个小伙子拉去代码到他自己的机子上,执行 yarn install
。无论 lodash 发布了射门版本,他安装的版本一定是 3.9.1,因为具体要安装的版本已经明确写到 yarn.lock
文件中了。
如何升级依赖?
yarn upgrade
yarn upgrade
命令允许我们升级 package.json
文件中的依赖列表,升级至规定的范围内。假设 lock file 的 lodash 版本是 3.9.1,并且现在 lodash 可获得的版本是 3.10.3,执行 yarn upgrade
会安装版本 3.10.3 并且 yarn.lock
文件会更新为如下。
lodash@^3.9.1: version "3.10.3" ...
升级依赖到最新版本
我们可以通过 yarn upgrade --latest
,把依赖升级至最新版本,不受 package.json
规定的版本范围限制。
以下 package.json
:
"dependencies": { "lodash": "^3.9.1" }
如果 lodash 发布了 4.17.14 版本,我们可以运行 yarn upgrade --latest
安装最新版本 4.17.14 并且会更新 yarn.lock
文件为如下:
lodash@^4.17.14: version "4.17.14" ...
yarn 会自动更新 package.json
文件里的版本范围,像这样。
"dependencies": { "lodash": "^4.17.14" }
交互式升级版本
我们项目里会有很多依赖,有一个视图可供选择依赖升级非常有用。
yarn upgrade-interactive [--latest]
,执行升级前,会显示哪些依赖过时了以及依赖的最新版本,允许我们自己选择要升级的依赖。如果没有 --latest
,确定要升级时会在 package.json 规定版本范围内升级,如果指定了 --latest
则会忽略 package.json
的版本范围限制。