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.

An image showing that your application points to the Express pacakge, meaning it depends on it.
Your application’s direct dependency on 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.

Your application points to the Express package, which in turn points to the send package.
Express depends on `send`, which causes it to be downloaded when installing your application’s dependencies

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.

Your application points to the Express package, which points to the send package, which then points to the mime-types package.
The `send` package depends upon `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

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist

Leave a Reply

Your email address will not be published. Required fields are marked *