28

What is the point of putting npm's package-lock.json under version control? In my experience having this file source controlled has caused more trouble and confusion than efficiency gains.

Having package-lock.json under source control makes for a major headache every time a developer who added/removed/modified any node modules needs to resolve conflicts between branches. Especially working on a complex/large apps where the package-lock.json can be tens of thousands of lines long. Even just blowing away node_modules and running a fresh npm install can generate drastic changes in the package-lock.

There are several other SO questions about the package-lock:

And a GitHub issue with a ton of conversation about package-lock:

Which makes me think there is still widespread uncertainty that needs cleared up.

According to the docs

package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json.

So why would you ever want to put an automatically generated file under source control?

The above GitHub issue details how some people, in response to confusion with the package-lock.json, change their npm install script to rm -f package-lock.json && npm install, which also does not feel correct.

It seems like package-lock.json is striving to be the source of truth for the exact version of node module dependencies, but isn't that exactly what the package.json does? When does the excruciating pain of resolving merge conflicts in this file start to pay off?

Cumulo Nimbus
  • 6,542
  • 7
  • 43
  • 61
  • Your team should have agreed to solely follow the "current working" module versions in your package-lock.json every time there's a code change unless you all agree that a current module needs to be upgraded. This way, package-lock.json let everyone know which module version is required and "currently working" with your application. – winux Aug 03 '20 at 04:30

3 Answers3

11

In my experience, it does not make sense to put package-lock.json under version control. It makes managing large merge/rebases a nightmare. However, there are instances where the package-lock can be very useful.

Recently (2017/10/10) moment.js introduced breaking changes in a minor version update. Meaning if one was to ship with no package-lock.json, and had something like this in their package.json:

"moment": "^2.12.0"

Some breaking changes introduced in version 2.19.0 would silently infiltrate your code with almost no trace.

This is why after cutting a branch to serve as a release candidate it is crucial to:

  • remove package-lock.json from .gitignore
  • run npm install to generate a package-lock.json
  • test, qa, deploy with this package-lock

This assures your npm module versions will remain locked down on the same versions that were tested.

Cumulo Nimbus
  • 6,542
  • 7
  • 43
  • 61
  • Locking down versions, isn't that what `npm shrinkwrap` is for? – strider Nov 16 '17 at 17:44
  • 9
    Isn't doing a breaking change in a minor version update also a big no-no? – Jankapunkt Feb 27 '18 at 15:54
  • 9
    True, but this is just a gentleman's agreement. Doesn't always hold true in the real world – Cumulo Nimbus Mar 26 '18 at 22:41
  • 4
    Downvoting. Lockfiles should always be in version control, or else you can’t have repeatable builds. – Marnen Laibow-Koser Mar 18 '19 at 21:40
  • I agree, lockfiles should be submitted to version control. However after running `npx create-react-app` I am now staring down a `package-lock.json` with 38k lines. That is 38 **thousand** lines and more than 1kb in size. This is simply way too large to version control. – Attila Viniczai Nov 23 '20 at 21:08
4

Create a .gitattributes entry:

# common settings that generally should always be used with your language specific settings

# Auto detect text files and perform LF normalization
* text=auto

#
# The above will handle all files NOT found below
#

#*.svg text
*.lock binary

Then when you merge you will only have to choose a version vs code merges. Thought you might run into package conflicts this way.

We have mitigated that by checking versions in the build process.

Marcos Dimitrio
  • 5,592
  • 3
  • 33
  • 56
Fitch
  • 326
  • 3
  • 4
  • 3
    The `*.lock` in the last line of the .gitattributes shown does not seem to make sense as the this is about `package-lock.json`. Did you mean `package-lock.json binary` instead? – Adrian W Jun 28 '18 at 16:37
  • I really like this answer as a general concept, but like @Adrian, I think the use of *.lock binary isn't exactly what you might want. After reading https://git-scm.com/docs/gitattributes, I am going to try using *lock.json -diff in my .gitattributes file to see if that works. Additionally, the line with * text=auto is irrelevant to the question. – Josh Desmond Jul 10 '19 at 20:42
2

IMO package-lock.json (or yarn-lock.json) should always be committed to source control. Merge/rebase conflicts aside (which are largely mitigated by yarn BTW - you can yarn install mid-rebase to resolve issues automatically), it is the best guarantee you have that the code at that commit will build and run correctly after a fresh checkout and install.

linguamachina
  • 4,645
  • 1
  • 18
  • 22