What is the point of having same dependency tree ? And how does dependency tree actually work ? Should I commit package-lock.json every time I add new package ? How is it related to symbols (e.g. ^ ) that are put before package versions in package.json ?
There are four different ways you could say you need to have ice cream:
ice-cream: *
)ice-cream: ^1.0.0
)ice-cream: ~1.0.0
)ice-cream: 1.0.0
)Regardless, when you get your ice cream, it's chocolate with chocolate sprinkles. You're now locked into that. If you want your friend to have ice cream, too, you can give him the lock so you're both enjoying the same ice cream. If it doesn't matter exactly having the same ice cream in this moment, though, you can just give him those instructions I called out above rather than also giving him the lock.
Now that your friend is getting ice cream without a lock, he might get:
ice-cream: *
)ice-cream: ^1.0.0
)ice-cream: ~1.0.0
)ice-cream: 1.0.0
)If we're cool with him maybe working with different ice cream than you, then awesome! If not, if maybe he's a dude who is trying to figure out whether or not to invest millions into your ice cream and he got something totally different, then you should probably give him the lock file to make sure you guys are on the same page.
Say I have specified ice-cream: ^ 1.0.0 in package.json and given him the lock file. Now ice-cream 1.1.0 is available, shouldn't he be getting 1.1.0 because my package.json has ^ symbol specified?
Keeping the ice cream metaphor because I think I'm clever:
When you're starting your ice cream business, it may not actually matter what kind of ice cream. You're focused on getting marketing and a retail location and stuff like that, so strawberry ice cream wouldn't kill things right now.
But once you open your business, your customers need reliability. Now that they've seen chocolate ice cream with chocolate sprinkles on the menu, they want to keep coming back for that.
That's why there would be a difference in dev dependencies, application dependencies, but also wanting to have a specific version actually deployed every time. The app just needs ice cream, you developing might need chocolate ice cream to test consistently, but now the server should always build with chocolate ice cream with chocolate sprinkles so no quirks from peanut allergies make it into production.
No, it reads the
package-lock.json
.package.json
is for you as the developerpackage-lock.json
is for me (or the server) as the installerThe package.json will be considered only if the lock is missing, hence the reason why they invented the lock, because the
package.json
is not enough to guarantee repeatabilityThe lock file main purpose is repeatability of the installs.
If you have it you can be sure the packages listed there are the same that are going to be installed on your production application.
If you only have the
package.json
you will probably end up with slightly different versions for the same packages.Yes
When you specify your dependencies you have multiple ways to specify a dependency. You can list the exact version (but it means you have to change both package.json and the lock file every time there's a new version) or you can use semver which allows you to be a little more elastic.
^1.2.3
for example means install all the1.x.x
future versions because the agreement says: "1 is the major version, 2 is the minor version, 3 is the patch version". So the developer likely won't release incompatible software until the version goes from1.x.x
to2.x.x
, and such version won't be intercepted by your initial rule^1.2.3
. If instead you only want bugfixes (the last digit) you can use~1.2.3
which means install all the1.2.x
versions.Thank you for your response.
I'm still kinda confused.
To have the same package AND the same version installed everywhere you need to specify the version, for example
In theory this guarantees that your
hello
package is installed with the same version everywhere. Unfortunately it doesn't guarantee that any other library thathello
uses as a dependency will be installed with the same version. For this, you need the lock fileYes but only when you add a package. If the version you allow points to
1.3.0
the lock file will be updated when you runnpm install
.Yes, you are. When you install (and not add) a package, the
package.json
is totally bypassed. What npm does is read thepackage-lock.json
and install the exact versions specified thereOh.. Thanks for the clarification 😊
I don't think I'm able to answer everything, but here's at least some points:
The
^
in^3.0.0
indicates that the package needs to be at least version3.0.0
. So having version2.9.9
installed on the machine would require an update to version3.0.0
or newerThe purpose of
package-lock.json
is to outline the list of version requirements for each package. This is useful for 2 reasons:fancyTool.js v. 1.1.0
that you implement, you wouldn't want users to installv. 1.0.0.
and wonder why it isn't working.v. 1.0.0
tov. 2.0.0
, you want to be able to require thatv. 1.0.0
be installed instead ofv. 2.0.0
(which would in turn break your program).Then why to have both package-lock.json and those symbols in package.json ? Purpose of both of these things is same right ? How do they work together ?
The symbols are part of the
package-lock.json
structure. Each package independently can be assigned either a specific version or a minimum version that is needed. i.e.)In this example,
cookie
,cookie-signature
, anddebug
will install their specific versions anddepd
needs at least1.1.1
, but would also accept something like2.0.0
or1.2.1
A small thing to add here regarding lock files is speed. If your repo don't have a lock file, NPM (or any package manager) check all existing version of your dependencies and install the ones matching what you asked for. The same process if repeated for all sub-dependencies and so on.
Lock file remove this roundabout, it don't need to check to know "who need what" or "what version match this".
I just test on a project:
Package-lock.json is the building instructions that comes with a Lego model.
Each package represents the different shapes or colour for a part that you eventually use to build a Lego model out of it.
Without a package-lock.json, it is like you are spreading it around and mixing with different Lego parts that do not come with the box.
By using symbols, you allow different types of the part to build your Lego model.
Which each part could be switched from an older Lego model you had brought previously or a new box of Lego model you had brought just now.
I just got one of these. So, basically, I do nothing? Include it in git commits, and that's it?
Yes, make sure it's committed along with package.json changes.
Thanks!!