第一次,首先执行 yarn install ,会按照语义版本控制规则(在下面会解释)下载最新的依赖包并且构建为依赖关系树,也就是把共有的部分提取出来。然后生成 yarn.lock 文件。并且生成本地缓存。 以后执行 yarn install 会先对比 package.json 版本号和 yarn.lock 版本号是否一致。分两种情况: (1)如果不一致会根据package中的版本号以及语义版本控制规则去下载最新的包,并更新至 yarn.lock 。 (2)如果一致,会根据lock查看缓存进行复制,没有缓存就按照路径下载,注意:这里 不会理会package实际包的版本是否有更新 。这个比如删除 node_moudles 后再执行 yarn install 会复制缓存,而不是重新下载,同时也会根据 yarn.lock 文件中依赖的相互关系生成依赖树,版本也和package中的相同。
yarn install
yarn.lock
package.json
node_moudles
npm5中是 如果改了 package.json ,且 package.json 和 package-lock.json 文件中包版本号不一致,那么执行 npm i 时npm会根据package中的版本号以及语义含义去下载最新的包,并更新至lock。如果两者是同一状态,那么执行 npm i 都会根据lock下载,不会理会package实际包的版本是否有新。和yarn是一样的。
package-lock.json
npm i
从npm版本看 package-lock.json 是npm5的新特性,也不向前兼容,如果npm版本是4或以下,那得用 npm-shrinkwrap.json
npm-shrinkwrap.json
从npm处理机制来看
npm install
npm init
npm shrinkwrap
从文件更新来看 npm-shrinkwrap.json 只会在运行 npm shrinkwrap 才会创建/更新 package-lock.json 会在修改 pacakge.json 或者 node_modules 时就会自动产生或更新了。
pacakge.json
node_modules
从发布包来看 package-lock.json 不会在发布包中出现,就算出现了,也会遭到npm的无视。 npm-shrinkwrap.json 可以在发布包中出现
项目 package.json 中包版本号前如果有 ^ ~ 之类的会按照 语义版本控制规则 (也可以看下这个博客 https://blog.csdn.net/ZQ_KING/article/details/81560075 )安装规则下最高版本的包(只限定于没有lock文件时候。如果有lock文件会根据lock文件中的下载路径下载,当然你可以在有lock文件情况下 yarn upgrade vue ,就会按照语义规则下最高版本的包下载)。但是 package.json 中的对应包的版本号没变,只改变了 yarn.lock 中对应包的部分信息和 node_moudles 中的对应包。(比如执行yarn upgrade vue时vue:2.6.5的包会下载2.6.5的包,vue:^2.6.5的包会下载2.6.10最新的包,如果yarn upgrade vue@版本号就会下载对应版本的包) 比如拿vue这个包来说,现在最高版本号是 2.6.10 ,我 package.json 文件中版本号是 ^2.6.6 ,当 yarn install 时,它会下载 >=2.6.6 <3.0.0 间最大的就是 2.6.10 版本号的vue包(只限定于没有lock文件,有lock文件会根据lock中的路径下载对应版本)。它会先更新 node_moudles 然后更新 yarn.lock 中vue包内容。下载完成后 package.json 中vue版本号还是 vue : ^2.6.6 ,更新 yarn.lock 文件中vue包的详细信息为: 实际上 node_moudles 中下载的是 2.6.10 版本的。所以说提不提交 yarn.lock 到代码托管平台是有争议的,因为提交了可能依赖会有地雷,不提交依赖关系可能会出错,一般来说是应该提交的。可以看这个( 为什么我不使用 shrinkwrap(lock) )
^ ~
yarn upgrade vue
2.6.10
^2.6.6
>=2.6.6
<3.0.0
vue : ^2.6.6
yarn.lock 是为了维护树关系,保证依赖间的相互关系,和包的下载路径。如果改了 package.json 版本号,且 package.json 和lock文件版本号不同,那么执行 yarn install 时,会根据package中的版本号以及语义含义去下载最新的包,并更新至lock。这也是 yarn.lock 提交到代码托管平台的原因。因为安装依赖时会按照lock中下载路径走,并且不需要重新生成依赖关系树了,其他机器 yarn install 时包间依赖关系和版本就不会出现的错误。npm中 npm install 有可能会因为包间的版本不同导致版本和依赖错误(除非有package.lock.json文件)。
总的来说 yarn.lock 和 package-lock.json 起的作用相同。只不过yarn是默认的,npm到5以后才会出现lock。两者确定包间的依赖关系算法也不同,总之yarn就是为了弥补npm的缺陷而出现的。
yarn: https://yarn.bootcss.com/docs/dependency-versions/ (版本范围规则) https://yarn.bootcss.com/blog/2016/11/24/lockfiles-for-all/ (yarn.lock文件应该提交到托管平台上) https://yarn.bootcss.com/docs/yarn-lock/ (yarn.lock文件解释)
npm: https://www.zhihu.com/question/264560841 (package-lock.json 需要写进 .gitignore 吗?) https://juejin.im/post/5c53bea8e51d457fbe226efb (对npm包精准控制之npm-shrinkwrap.json与package-lock.json) https://zhuanlan.zhihu.com/p/22934066 (为什么我不使用 shrinkwrap(lock))
夜里因为这个睡不着,导致第二天还睡过头了只能请假。最后,觉得有帮助的点个赞o~~