Do I commit the package-lock.json file created by npm 5?
Solution 1:
Yes, package-lock.json
is intended to be checked into source control. If you're using npm 5+, you may see this notice on the command line: created a lockfile as package-lock.json. You should commit this file.
According to npm help package-lock.json
:
package-lock.json
is automatically generated for any operations where npm modifies either thenode_modules
tree, orpackage.json
. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.This file is intended to be committed into source repositories, and serves various purposes:
Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
Provide a facility for users to "time-travel" to previous states of
node_modules
without having to commit the directory itself.To facilitate greater visibility of tree changes through readable source control diffs.
And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.
One key detail about
package-lock.json
is that it cannot be published, and it will be ignored if found in any place other than the toplevel package. It shares a format with npm-shrinkwrap.json, which is essentially the same file, but allows publication. This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages.If both
package-lock.json
andnpm-shrinkwrap.json
are present in the root of a package,package-lock.json
will be completely ignored.
Solution 2:
Yes, you SHOULD:
- commit the
package-lock.json
. -
use
npm ci
instead ofnpm install
when building your applications both on your CI and your local development machine
The npm ci
workflow requires the existence of a package-lock.json
.
A big downside of npm install
command is its unexpected behavior that it may mutate the package-lock.json
, whereas npm ci
only uses the versions specified in the lockfile and produces an error
- if the
package-lock.json
andpackage.json
are out of sync - if a
package-lock.json
is missing.
Hence, running npm install
locally, esp. in larger teams with multiple developers, may lead to lots of conflicts within the package-lock.json
and developers to decide to completely delete the package-lock.json
instead.
Yet 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.
From a package-lock.json
you get exactly that: a known-to-work state.
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.
Those issue are hard to resolve as you sometimes have to guess what the last working version was.
If you want to add a new dependency, you still run npm install {dependency}
. If you want to upgrade, use either npm update {dependency}
or npm install ${dependendency}@{version}
and commit the changed package-lock.json
.
If an upgrade fails, you can revert to the last known working package-lock.json
.
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.
Note: I posted a similar answer here
Solution 3:
Yes, it's intended to be checked in. I want to suggest that it gets its own unique commit. We find that it adds a lot of noise to our diffs.
Solution 4:
Yes, the best practice is to check-in (YES, CHECK-IN)
I agree that it will cause a lot of noise or conflict when seeing the diff. But the benefits are:
-
guarantee exact same version of every package. This part is the most important when building in different environments at different times. You may use
^1.2.3
in yourpackage.json
, but how can you ensure each timenpm install
will pick up the same version in your dev machine and in the build server, especially those indirect dependency packages? Well,package-lock.json
will ensure that. (With the help ofnpm ci
which installs packages based on lock file) - it improves the installation process.
- it helps with new audit feature
npm audit fix
(I think the audit feature is from npm version 6).