To lock the versions of dependencies that are installed over a project, the command npm install
creates a file called package-lock.json
. This was made since Node.js v8.0.0 and npm v5.0.0, as several of you might know.
Despite of Node.js and npm recommendations about committing this file, several concerns regarding when you should avoid to do it, are also an option. Typically we commit in our projects, nevertheless, it is a peculiar question.
While we should commit the package-lock.json
file by default, we have a specific case we should not. For instance, if we want to test the latest version of our project dependencies, it can be an option to add package-lock.json
into .gitignore
.
So, the questions are as follows:
package-lock.json
file be added to .gitignore
?json intact. It is highly recommended you commit the generated package lock to source control: this will allow anyone else on your team, your deployments, your CI/continuous integration, and anyone else who runs npm install in your package source to get the exact same dependency tree that you were developing on.
The package-lock. json file needs to be committed to your Git repository, so it can be fetched by other people, if the project is public or you have collaborators, or if you use Git as a source for deployments. The dependencies versions will be updated in the package-lock. json file when you run npm update .
Why you should never delete package-lock. json. When you install a dependency for the first time, it is usually automatically added to your dependencies or devDependencies with ^version , which means "compatible with version, according to semver".
You should never, ever "gitignore" your lock files( package-lock. json and/or yarn. lock )! Even when installing using npm install , it generates a notice that we "should commit this file".
No, the package-lock.json
SHOULD NOT be added to .gitignore
. Instead, I strongly advise:
package-lock.json
you to your version control repositorynpm ci
instead of npm install
when building your application both locally and in your deployment pipeline.ci
command is available since [email protected], if in doubt upgrade your npm via:npm install -g npm
.)One of the biggest downside of the npm install
command is its unexpected behavior that it may mutate the package-lock.json
, whereas npm ci
only uses the version in the lockfile and produces an error if the package-lock.json
and package.json
are out of sync.
Also, npm ci
requires the existence of a package-lock.json
and would print an error if it wasn't there.
There is a strong use-case for being able to trust that the project's dependencies resolve repeatably in a reliable way across different machines.
Furthermore, npm ci
nukes the entire node_modules
folder before adding the dependencies making sure you work with your actual dependencies instead of local changes while still being faster than a normal npm install
.
From a package-lock.json
you get exactly that: a known-to-work state with always exactly the same dependency tree.
In the past, I had projects without package-lock.json
/ npm-shrinkwrap.json
/ yarn.lock
files whose build would fail one day because a random dependency got a breaking update. (While a lot of libraries respect the semvar versioning guideline, you have no guarantee they won't break on a minor upgrade.)
Those issue are hard to resolve as you sometimes have to guess what the last working version was.
In regards to testing the latest dependencies for your project: This is what npm update
is for and I argue that it should be run by a developer, who also runs the test locally, who resolves issue if they may arise, and who then commits the changed package-lock.json
. (If an upgrade fails, they can revert to the last working package-lock.json
.)
Furthermore, I rarely upgrade all the dependencies at once (as that too might require further maintenance) but I rather cherry-pick the update I need (e.g. npm update {dependency}
, or npm install {dependency}@2.1.3
). Which is another reason why I would see it as a manual maintenance step.
If you really want to have it automated you could create a job for:
This is something I would see hosted on a CI server, e.g. Jenkins, and it should not be achieved through aforementioned reason through adding the file to the .gitignore
.
Or to quote npm doc:
It is highly recommended you commit the generated package lock to source control: this will allow anyone else on your team, your deployments, your CI/continuous integration, and anyone else who runs npm install in your package source to get the exact same dependency tree that you were developing on. Additionally, the diffs from these changes are human-readable and will inform you of any changes npm has made to your node_modules, so you can notice if any transitive dependencies were updated, hoisted, etc.
And in regards to the difference between npm ci
vs npm install
:
- The project must have an existing package-lock.json or npm-shrinkwrap.json.
- If dependencies in the package lock do not match those in package.json,
npm ci
will exit with an error, instead of updating the package lock.npm ci
can only install entire projects at a time: individual dependencies cannot be added with this command.- If a
node_modules
is already present, it will be automatically removed beforenpm ci
begins its install.- It will never write to
package.json
or any of the package-locks: installs are essentially frozen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With