NPM and yarn.lock

Viewed 547

Since NPM v7 the official docs state the following about npm install (emphasis mine):

This command installs a package and any packages that it depends on. If the package has a package-lock, or an npm shrinkwrap file, or a yarn lock file, the installation of dependencies will be driven by that

I was trying to find more information about npm install behavior with the yarn.lock present, but didn't find much. This blog post states:

With the new package-lock.json file we'll unlock the ability to do deterministically reproducible builds. It should now include everything npm needs to install the packages needed. Before npm 7 yarn.lock was ignored by npm, but this is no longer the case. It can now use it to keep itself up to date with the package tree.

GitHub blog:

In prior versions, the yarn.lock files were ignored, the npm CLI can now use yarn.lock as the source of package metadata and resolution guidance. If a yarn.lock file is present, then npm will also keep it up-to-date with the contents of the package tree.

But neither of them gives a clear picture of what actually happens when I run npm install with yarn.lock.

I'd like to get a grasp on it:

  • Can I run yarn locally to generate yarn.lock and reproduce the package tree on CI with npm install?
  • What exactly happens when I run npm install with yarn.lock? Does it get updated? Can it be run with (sort of) --frozen-lockfile? The npm ci command doesn't mention yarn.lock at all.
  • Does it support both v1 and berry?
3 Answers

Can I run yarn locally to generate yarn.lock and reproduce the package tree on CI with npm install?

No, you still need a package-lock.json file if you want to reproduce the package tree using npm v7. v7 only uses the yarn.lock file as a source of package metadata and resolution guidance.

This is because npm v7 generates the lockfiles with the a new lockFileVersion: 2 (backward compatible) to improve performance and allow reproducible builds with deterministic tree shape; it also tries to reduce reading from package.json file for metadata.

What exactly happens when I run npm install with yarn.lock? Does it get updated? Can it be run with (sort of) --frozen-lockfile? The npm ci command doesn't mention yarn.lock at all.

Yes, the yarn.lock file will be updated and npm will still create a package-lock.json file, and if a package-lock.json file is present, it’ll be used as the authoritative definition of the tree shape to create.

As per this NPM blog post, the reason they don't support yarn.lock file yet is

One common question we’ve gotten a few times now, once we announce that npm v7 will include support for yarn.lock files, is “Why keep package-lock.json at all, then? Why not just use yarn.lock only?”

The simple answer is: because yarn.lock doesn’t fully address npm’s needs, and relying on it exclusively would limit our ability to produce optimal package installs or add features in the future.

Finally,

Does it support both v1 and berry?

This is not clear, and is implied to change for berry as yarn uses a combination of yarn.lock file and yarn version to guarantee deterministic resolution.

I suggest reading this blogpost along with the above post from npm for more in-depth explanation.

Since you have done so much research and it seemed further document searching wouldn't alleviate your uncertainty, why not take a future step to take a look at the source code? Don't be afraid to read code

So, I did a superficial search on the repo https://github.com/npm/cli and found this file can answer your question

For takeaway,

Can I run yarn locally to generate yarn.lock and reproduce the package tree on CI with npm install?

Yes, unless you use some protocols only attributed to berry and unsupported by npm

What exactly happens when I run npm install with yarn.lock? Does it get updated? Can it be run with (sort of) --frozen-lockfile? The npm ci command doesn't mention yarn.lock at all.

  1. When you run npm i, yarn.lock will get updated. At least it will make some formatting changes and overwrite the registry URL. If npm cannot find the resolved version of a package or the resolved version isn't valid, it will get it from the registry and update in both package-lock.json and yarn.lock.
  2. npm ci requires package-lock.json otherwise it will exit immediately

Does it support both v1 and berry?

it don't work well with berry. npm will overwrite the yarn.lock with the format of yarn lockfile v1

This doc should help explain a bit: https://blog.npmjs.org/post/621733939456933888/npm-v7-series-why-keep-package-lockjson.html#:~:text=While%20npm%20uses%20the%20yarn,t%20ideal%20in%20these%20cases.

This link explains a bit on yarn and npm interacting tho on the idea that your switching from npm to yarn, so kinda the opposite but a list of comparison commands (CI) that could be interesting to view: https://classic.yarnpkg.com/lang/en/docs/migrating-from-npm/

I don't know much about the difference other then Yarn install faster and the packages are built a little different. Couldn't find a doc that explains switching to npm. Delete the yarn.lock before starting npm. Otherwise, see above answer.

Related