What is the `version` in yarn.lock `__metadata`? - yarnpkg

At the top of my yarn.lock file I see:
__metadata:
version: 5
cacheKey: 8
I have no idea what the version or cacheKey is, and I haven't found any documentation for them on yarn's website. What are they?

It's simply the yarn.lock version, originally introduced here:
When upgraded, the lockfile entries have to be resolved again (but the specific versions are still pinned, no worry). Bump it when you change the fields within the Package type; no more no less.
More details on the currently implemented resolution logic:
github.com/yarnpkg/berry/blob/master/packages/yarnpkg-core/sources/Project.ts
Typical scenario
My lockfile version updated locally because my latest Homebrew Yarn version was running behind on 3.2.0-rc.10, despite running brew upgrade and yarn -v still showing this older version.
However a bot (might be team member) already upgraded Yarn to 3.2.0-rc.12, versioned / committed / locked remotely in .yarnrc.yml and npm.packageManager (example).
This is what we want for consistency, so we could add a package.json script to use it instead
// ...
"scripts": {
// ...
"setup": "yarn",
// ...
// ...
If frequently switching between classic, stable and canary - cd ~ && yarn set version <ver> may bump your local Yarn version too (then remember to clear generated files).

Related

`yarn add` installs stale version of local .tgz

I am using yarn to install a package from a .tgz. When I update the package and install it again, yarn uses an old cached version of the package. Here is a report from someone running into a similar problem. If I try to delete the package from the cache, it gives me errors, and if I use yarn cache clean it will clear the whole cache, which is also not what I want.
The reason the package is changing is that I am developing it, and don't want to bump the version number every five minutes. I read maybe newer yarn versions take the package hash into account when installing, but I am stuck with version 1.22.1 (actually jlpm which is JupyterLab's vendored version of yarn).
Is there a way to say yarn add package-0.1.0.tgz --dont-use-cache? Or should I just skip yarn and use npm, or something else on top?

heroku doesn't install the changed version of npm package and installs old version instead

Problem
I was facing difficulty in importing one of the packages properly and using it in my MERN application in the backend. After researching and looking at the deployed code I got to know that my application is using the unwanted version of that package and thus it is causing the issue but I already changed the version in package.json before pushing. I have written unwanted here because in my case the new version of the package has bugs and that's why I want the old/previous version back but I am unable to know the exact reason or thing which is causing heroku to use the unwanted version again and again.
For Clarity:
initial version: 1.6.6 (was working fine)
then I installed version: 1.7.0 (found bugs) unwanted version
tried to go back to version: 1.6.6 but couldn't
What I have tried
The first thing I tried was setting NODE_MODULES_CACHE to false to avoid heroku from picking up old code as it has worked for me in the past. Apart from that I have I can't find any other thing.
There is nothing suspicious in the heroku logs and it builds the application without any error.
I found the solution to it if someone's looking for it. It is not much of a solution instead it's more about how heroku works.
Heroku uses npm ci instead of npm install.
npm ci installs all dependencies in respect to package-lock.json similar to npm install. The key difference here is that ci doesn't alter package-lock.json under any circumstances.
So basically, the package-lock.json was still the unwanted one in my case and heroku was installing that rather than what I pushed into package.json as it didn't matter.
So, in order to solve this issue you have two options:
You can push your updated package-lock.json. In my case I had intentionally not added package-lock.json to versioning as I thought heroku would update it so I had put it in .gitignore
You can set the USE_NPM_INSTALL environment variable to true to let Heroku know that you want to use npm install instead of npm ci to create the build environment. (NOTE: If you want to use npm install Heroku advises to use NODE_MODULES_CACHE=false as it speeds up the build time)
I went with option 1.
Link to Heroku docs: https://devcenter.heroku.com/articles/nodejs-support

Committing .yarn directory to git when using yarn berry

In the next version of yarn ("berry") the manual states that one should just commit the directory created called .yarn, but if you use the multi-version setup for yarn, this directory contains the file releases/yarn-berry.js which seems to be the entire berry version of yarn, taking up more than 2MB of disk.
This just seems really wrong - why should I commit a package manager to git, just to get it to work?
The Yarn developers explain the rationale for this in the Installation docs, in the section called "About global installs":
Using a single package manager across your system has always been a problem. To be stable, installs need to be run with the same package manager version across environments, otherwise there's a risk we introduce accidental breaking changes between versions - after all, that's why the concept of lockfile was introduced in the first place! And with Yarn being in a sense your very first project dependency, it should make sense to "lock it" as well.
Once Yarn is tracked and "locked" as a per-project dependency, it ends up getting committed to Git if you follow Yarn 2's zero-install strategy, the rationale for which is explained here.
I'm a newcomer to Yarn, but I spent years working devops, helping developers figure out why their code would sometimes build correctly on half of the team's laptops but not on the other half, or would suddenly start failing to build in CI while continuing to work elsewhere. Trying to keep the version of npm consistent across every computer and codebase in the company was essentially impossible, given that Node is constantly being upgraded, but locking each project to its own specific version of Yarn -- which, by being committed to Git, is guaranteed to be available in every checkout of that project -- solves this problem.
I have written a small tool for those people who don't want to commit Yarn 2+ binary into their git repos, while still benefiting from sticking Yarn version per project. If you already have Yarn 2+ configured in your project just don't want to commit it, you can run:
yarn dlx pinyarn
This command will generate .pinyarn.js (4KB) which you should commit, instead. .pinyarn.js will contain URLs inside to download Yarn 2+ and its plugins from the official Yarn Berry GitHub repo. .pinyarn.js will download binary and plugins from these URLs if they are not downloaded yet.
You can also specify which version of Yarn 2+ you want via:
yarn dlx pinyarn 3 - the latest released Yarn 3 version, or
yarn dlx pinyarn 2.2.2 - version 2.2.2, or
yarn dlx master - version from latest sources, or
yarn dlx 1638 - version from Pull Request 1638
The pinyarn tool repo on GitHub:
https://github.com/sysgears/pinyarn
The official documentation mentions what's should be ignored and what should be committed. It can solve this problem I think.
https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
The new docs states using node's newest corepack feature (to date).
This means that when using appropriate node you only need to place a valid packageManager field value in package.json and run corepack enable, e.g.
{
"name": "foo",
"packageManager": "yarn#3.2.0",
"scripts": {
...
}
}

Is there any harm in using NPM and Yarn in the same project?

I have been using npm for a personal project and just recently stumbled across yarn. Would there be any harm or "intended side effects" to switching to yarn's package manager in the same project where I had been using npm?
Although a few commenters here say its ok to mix both yarn and npm on the same project, after using yarn and npm and then yarn again, this is what yarn has to say about it:
warning package-lock.json found. Your project contains lock files generated by tools
other than Yarn. It is advised not to mix package managers in order to avoid resolution
inconsistencies caused by unsynchronized lock files. To clear this warning, remove
package-lock.json.
Since to me it is not any harm to using both them into one project.
I use npm and yarn (50/50) in dev environment.
But on ci/di i use only yarn because it is faster, and i reduce build minutes thanks yarn.
Also they both create different .lock file names.
Nobody told about the lock files.
Imagine you use yarn on dev environment, and yarn on your build/production servers. When you install a package using yarn, and your project works on your computer, you probably would want to keep it working on a production environment (your server).
That being sad, you would commit you yarn.lock file, that "saves" the exact versions of each package you have, when the project ran on your computer.
On your buid/production server you should call yarn install, but asking to keep all the same versions with --frozen-lockfile parameter. Some even say "yarn install --frozen-lockfile should be the default behavior", and I agree.
Then... another dev jump in the project you are working and install a package using npm (other than yarn). That new package will not be included in your yarn.lock file, but, a new package-json.lock file would be created, telling the exact packages versions it is using.
When that commit arrives on your build/production server, it will crash, fail, because that new package doesn't exist on yarn.lock file. Someone would need to pull that changes, call a yarn to install the dependences and update the lock file with the new package dependences, and push it again to the repo.
A quick point about using the lock file or not. If you call a 'yarn install' on your build/production server some weeks after the last install on your machine, the server would have many other new versions than your last "stable" version. It already happened to me many times.
I published recently the package-locks-checks, which help ensure you have not just one lock file but also locked each package version on your project.
There will be a point that one or both will no longer work and your project will be stuck at only using the existing lock file. Meaning, the issue probably will involve installation fails if you opt to reinstall without a lock file. And that also means failure to create a new lock file, so you are stuck with the existing one that you are trying to get rid off in the first place. We are actually encountering this issue in one of our projects. Because it is so big, no one tries to fix the issue and just rely on the existing lock file.
So, even if we say it's a rare case that it won't cause harm. Mixing npm and yarn should be avoided.
Here https://classic.yarnpkg.com/en/docs/migrating-from-npm/ we may find a confirmation that Yarn's resolution algorithm is compatible with NPM resolution algorithm.
Inside a npm project (with package.json) if you run yarn it will read your node_modules folder (using the resolution algorithm) and create a yarn.lock file with your project's locked dependency tree.
Based on that I assume that they are compatible inside the same project.
Update 30/04/2021
My original reply refers to yarn 1 (classic), although I've just created a React app with create-react-app tool and it creates the project's repository with package.json + yarn.lock by default. Again, another demonstration that it's fine (even with the warning mentioned by Dave Pile).
At the end of the day this is a matter of putting both together to work and checking yourself...
Plus you get a warning from yarn as Dave Pile said because we have to push *-lock.json files changes you have to consider using npm version >= 7 to make sure whenever you install packages by npm it will update your yarn-lock.json file too.
Because whenever you install the packages either by npm or yarn depends on what you have chosen for updating a dependency in the package.json (Using tilde ( ~ ) which gives you bug fix releases and caret ( ^ ) gives you backward-compatible new functionality) it will update you.lock file and since you have to push it might happen that you have different version of lock files.

Yarn upgrade - Is the new version saved?

Say I have a package.json file in an existing project. In there I have "some-package": "^1.0-01",, however I know that the latest version is 1.0-02
So I do yarn upgrade. However, package.json is not update, and still references the -01 version. The yarn.lock file however shows this:
some-package#^1.0-01:
version "1.0-02"
Is this expected behavior? When someone else does the yarn command, which version will they get. If they get the latest version, isn't it misleading to show -01 in package.json?
According to the documentation here,
yarn upgrade
This command updates all dependencies to their latest version based on
the version range specified in the package.json file. The yarn.lock
file will be recreated as well.
The tricky part is based on the version range specified in the package.json
This means that if your package.json has defined a particular semver like you've said, upgrade will only upgrade it according to the range defined there, i.e. ^1.0-01 should upgrade to 1.0-02 in both your package.json and yarn.lock files.
Now you've said that this is happening only in your yarn.lock file. Yarn provides a utility for checking for such clashes called check
Could you try running
yarn check
in your repository and tell us your findings?

Resources