Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between yarn/npm5 lockfiles and exact package versions?

Tags:

npm

yarnpkg

My simple question is: why can't I just use exact versions in my package.json? How is this different from a lockfile?

like image 954
user2061057 Avatar asked May 31 '17 06:05

user2061057


People also ask

Does Yarn install multiple versions of the same package?

With npm or yarn, you can install a package under a custom alias. This enables you to install multiple versions of a package in the same project.

What is difference between Dev dependencies and DevDependencies?

A dependency is a library that a project needs to function effectively. DevDependencies are the packages a developer needs during development. A peer dependency specifies that our package is compatible with a particular version of an npm package.

What is the difference between Yarn install and npm install?

As mentioned above, while NPM installs dependency packages sequentially, Yarn installs in-parallel. Because of this, Yarn performs faster than NPM when installing larger files. Both tools also offer the option of saving dependency files in the offline cache.


1 Answers

The main difference is that lockfiles also lock nested dependencies - all of the dependencies of your dependencies, and so on. Managing and tracking all of those changes can be incredibly difficult, and the number of packages that are used can grow exponentially.

There are also situations where you cannot manually specify that a particular version of a package should be used - consider 2 libraries that specify foo at ~1.0.0 and ~2.0.0 respectively. The difference in major version tells us that the API of foo@v1 is not going to match the API of foo@v2, so there's no way you could override the package version at your app level without causing conflicts and failures.

Finally, you might wonder "why have semver at all then? Why not just have all packages manually specify the exact version of their dependencies?" One of the main advantages of semver is it means you don't have to update every dependency in the tree whenever a sub-dependency updates. If I rely on foo, and foo relies on bar, and bar just had a critical bug that was patched, and we're using exact versions for everything, then foo must also be updated before I can get the fix. If foo and bar have different maintainers, or if foo is abandoned, that could take a while and I may need to fork the project (something I've done more than once in Java-land).

This is very useful for maintaining ecosystems of libraries because it fundamentally reduces the amount of maintenance work required per-node in the dependency tree, making it easier to extract libraries and patterns. I once had an early project where we were building a component library that used exact versions, and any time the core library containing shared functionality was updated, we had to submit a PR to each of the other packages to update the version, and sometimes followup PRs to components that depended on those. Needless to say, we consolidated the packages after a few months.

Hope that helps!

like image 171
pzuraq Avatar answered Oct 13 '22 05:10

pzuraq