When Yarn introduced a lock file (similar to
Gemfile.lock), it did it with an unexpected twist. If you need reproducible builds,
yarn.lock is not enough.
What is a lock file? Lock files ensure that the defined dependencies from files such as
package.json get pinned to specific versions. This later ensures parity on developers’ workstations, CI, and production.
Many people probably depend on Yarn doing the right thing and installing only the pinned versions from
yarn install. But, unfortunately, this is not the case…
The default behavior of
yarn install is that the
yarn.lock file gets updated if there is any mismatch between
yarn.lock. Weird, right?
(In comparison, other package managers such as RubyGems would only ever look at lock files and install the pinned versions from there.)
Luckily a solution exists. The documentation for the Classic Yarn (1.x) says:
If you need reproducible dependencies, which is usually the case with the continuous integration systems, you should pass –frozen-lockfile flag.
yarn install command for CI and production should look like this:
$ yarn install --silent --production=true --frozen-lockfile
There is a long-standing issue for making this a default, but the developers decided to leave it for a new Yarn version which is developed under the name Berry.
Some also say that you don’t need it as you can use pinned versions directly in
package.json. This only true to some extend, though, because you would have to specify all transitive dependencies as well.
If you still run without the
--frozen-lockfile flag, fix it today. It will save you some headaches later.
Also note, that the
--frozen-lockfile flag is changed to
--immutable in modern versions of Yarn and it’s a default for CI mode.
← IT'S OUT NOW
I wrote a complete guide on web application deployment. Ruby with Puma, Python with Gunicorn, NGINX, PostgreSQL, Redis, networking, processes, systemd, backups, and all your usual suspects.