When writing JavaScript applications, you describe its dependencies using a package.json
file. This file contains all of your applications direct dependencies and their versions.
package-lock.json
is automatically generated for any operations where npm modifies either the node_modules
tree, or package.json
.
Managing Packages
npm exists to make managing packages easy. Your projects might have hundreds of dependencies, each of those with a hundred others. To keep your mind away from dependency hell, npm was created so that with some simple commands, you could install and manage these dependencies and hardly ever have to think about them.
let´s say for example, you’re building a RESTful API using Express, .Your package.json
file will probably list express
as a dependency.
{
"name": "my-app",
"version": "1.0.0",
"main": "index.js",
"dependencies": {
"express": "4.0.0"
}
}
Whenever you ask others to clone and run your application, they need to install its dependencies using npm install
. Doing so will cause them to download the version 4.0.0
of Express.
When installing Express, a package upon which your application depends, you will also download all of the packages upon which Express itself depends. Among the packages upon which Express depends, you can find, for example, send
, a package which provides a static file server.
Additionally, when installing Express and, consequently, send
, you will have to install the dependencies of send
. Because send
depends on mime-types
, , a utility package to handle mime-types, NPM will install also install mime-types
.
The process of recursively downloads all of your packages’ dependencies and the dependencies of those dependencies is what causes your node_modules
folder to get heavy so quickly.
Even though you only listed express
as a dependency, if you check your node_modules
folder — the folder in which NPM stores dependencies — you will see that there are many more packages there. These packages are not only Express’ dependencies, but also the dependencies of all dependencies.
This dependency download process would be beautiful if it weren’t for the fact that npm install
doesn’t necessarily install the same dependencies given the same package.json
file.
Running npm install
in the afternoon can cause you to get different dependencies when compared to the npm install
your colleague ran in the morning, even though none of you changed the version of Express upon which the application depends, for example.
say it in other words
Let us say it in other words
Let’s say we create a new project that is going to use express. After running `npm init`, we install express: `npm install express — save`. with the version 4.15.4. So “express”: “^4.15.4” is added as a dependency within the package.json and that exact version is installed on your machine. Now maybe tomorrow, the maintainers of express release a bug fix, and so the latest version becomes 4.15.5. Then if someone were to want to contribute to your project, they would clone it, and run `npm install.’ Since 4.15.5 is a higher version with the same major version, that is installed for them. We both have express, but we have two different versions. Theoretically, they should still be compatible, but maybe that bugfix affected functionality that we are using, and our application would produce different results when run with express version 4.15.4 compared to 4.15.5.
The Goal
The purpose of the package-lock is to avoid the situation described above, where installing modules from the same package.json results in two different installs
How package-lock.json
solves the unstable dependency problem
The package-lock.json
file lists your application’s dependencies and the dependencies of all its dependencies. In other words, it describes which version of every single package you have installed. That’s why it’s so much longer than package.json
. Whenever you use package-lock.json
to install dependencies, you will get the exact same packages, it doesn’t matter whether you’re installing them now or in a thousand years when we’ll hopefully not be using keyboards anymore.
To install dependencies based on your package-lock.json
file, you should use npm ci
instead of npm install
.
npm ci
By using npm ci
you will be able to avoid problems which happen when an application works in your machine, but doesn’t work in someone else’s because they ended up downloading different dependencies due to using npm install
.
That’s why, whenever running your builds in a Continuous integration server, you should install dependencies using npm ci
instead of npm install
. Doing so will cause the CI server’s build to run just like it had run in your machine.
Reference:
https://medium.com/coinmonks/everything-you-wanted-to-know-about-package-lock-json-b81911aa8ab8
https://lucasfcosta.com/2020/10/17/lockfile-guide.html
https://blog.coodoo.io/fragen-rund-um-die-package-lock-json-e7ff95fe4d6f