1PACKAGE-LOCKS(5)                                              PACKAGE-LOCKS(5)
2
3
4

NAME

6       package-locks - An explanation of npm lockfiles
7
8   Description
9       Conceptually,  the  "input"  to  npm  help  install is a npm help pack‐
10       age.json, while its "output" is a  fully-formed  node_modules  tree:  a
11       representation of the dependencies you declared. In an ideal world, npm
12       would work like a pure function: the same package.json  should  produce
13       the  exact  same  node_modules  tree,  any time. In some cases, this is
14       indeed true. But in many others, npm is unable to do  this.  There  are
15       multiple reasons for this:
16
17       · different  versions  of npm (or other package managers) may have been
18         used to install a package, each using slightly different installation
19         algorithms.
20
21       · a  new  version  of  a direct semver-range package may have been pub‐
22         lished since the last time your packages were installed, and  thus  a
23         newer version will be used.
24
25       · A  dependency  of  one  of your dependencies may have published a new
26         version, which will update even if you used pinned dependency  speci‐
27         fiers (1.2.3 instead of ^1.2.3)
28
29       · The  registry  you  installed  from is no longer available, or allows
30         mutation of versions (unlike the primary npm registry), and a differ‐
31         ent version of a package exists under the same version number now.
32
33
34       As an example, consider package A:
35
36         {
37           "name": "A",
38           "version": "0.1.0",
39           "dependencies": {
40             "B": "<0.1.0"
41           }
42         }
43
44       package B:
45
46         {
47           "name": "B",
48           "version": "0.0.1",
49           "dependencies": {
50             "C": "<0.1.0"
51           }
52         }
53
54       and package C:
55
56         {
57           "name": "C",
58           "version": "0.0.1"
59         }
60
61       If  these  are  the  only versions of A, B, and C available in the reg‐
62       istry, then a normal npm install A will install:
63
64         A@0.1.0
65         `-- B@0.0.1
66             `-- C@0.0.1
67
68       However, if B@0.0.2 is published, then  a  fresh  npm  install  A  will
69       install:
70
71         A@0.1.0
72         `-- B@0.0.2
73             `-- C@0.0.1
74
75       assuming  the  new  version did not modify B's dependencies. Of course,
76       the new version of B could include a new version of C and any number of
77       new  dependencies.  If  such  changes  are undesirable, the author of A
78       could specify a dependency on B@0.0.1. However, if A's author  and  B's
79       author  are  not  the same person, there's no way for A's author to say
80       that he or she does not want to pull in newly published versions  of  C
81       when B hasn't changed at all.
82
83       To  prevent  this  potential issue, npm uses npm help package-lock.json
84       or, if present, npm help npm-shrinkwrap.json. These  files  are  called
85       package locks, or lockfiles.
86
87       Whenever  you  run  npm  install, npm generates or updates your package
88       lock, which will look something like this:
89
90         {
91           "name": "A",
92           "version": "0.1.0",
93           ...metadata fields...
94           "dependencies": {
95             "B": {
96               "version": "0.0.1",
97               "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
98               "integrity": "sha512-DeAdb33F+"
99               "dependencies": {
100                 "C": {
101                   "version": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
102                 }
103               }
104             }
105           }
106         }
107
108       This  file  describes  an  exact,  and  more  importantly  reproducible
109       node_modules tree. Once it's present, any future installation will base
110       its work off this file, instead of  recalculating  dependency  versions
111       off npm help package.json.
112
113       The  presence  of a package lock changes the installation behavior such
114       that:
115
116       1. The module tree described by the package lock  is  reproduced.  This
117          means  reproducing  the  structure  described in the file, using the
118          specific files referenced in "resolved" if available,  falling  back
119          to normal package resolution using "version" if one isn't.
120
121       2. The tree is walked and any missing dependencies are installed in the
122          usual fashion.
123
124
125       If preshrinkwrap, shrinkwrap or postshrinkwrap are in the scripts prop‐
126       erty of the package.json, they will be executed in order. preshrinkwrap
127       and shrinkwrap are executed before the  shrinkwrap,  postshrinkwrap  is
128       executed  afterwards.  These scripts run for both package-lock.json and
129       npm-shrinkwrap.json. For example to run some postprocessing on the gen‐
130       erated file:
131
132           "scripts": {
133             "postshrinkwrap": "json -I -e \"this.myMetadata = $MY_APP_METADATA\""
134           }
135
136   Using locked packages
137       Using a locked package is no different than using any package without a
138       package lock:  any  commands  that  update  node_modules  and/or  pack‐
139       age.json's  dependencies will automatically sync the existing lockfile.
140       This includes npm install, npm rm, npm update,  etc.  To  prevent  this
141       update from happening, you can use the --no-save option to prevent sav‐
142       ing altogether, or --no-shrinkwrap to allow package.json to be  updated
143       while leaving package-lock.json or npm-shrinkwrap.json intact.
144
145       It  is  highly  recommended  you  commit  the generated package lock to
146       source control: this will allow anyone else on your team, your  deploy‐
147       ments,  your  CI/continuous  integration,  and anyone else who runs npm
148       install in your package source to get the exact  same  dependency  tree
149       that you were developing on. Additionally, the diffs from these changes
150       are human-readable and will inform you of any changes npm has  made  to
151       your  node_modules,  so  you  can notice if any transitive dependencies
152       were updated, hoisted, etc.
153
154   Resolving lockfile conflicts
155       Occasionally, two separate npm install will create package  locks  that
156       cause merge conflicts in source control systems. As of npm@5.7.0, these
157       conflicts can be resolved by  manually  fixing  any  package.json  con‐
158       flicts,  and  then running npm install [--package-lock-only] again. npm
159       will automatically resolve any conflicts for you  and  write  a  merged
160       package lock that includes all the dependencies from both branches in a
161       reasonable tree. If --package-lock-only is provided, it  will  do  this
162       without also modifying your local node_modules/.
163
164       To   make   this   process   seamless   on   git,  consider  installing
165       npm-merge-driver https://npm.im/npm-merge-driver, which will teach  git
166       how  to  do  this  itself without any user interaction. In short: $ npx
167       npm-merge-driver install -g will let you do this, and even  works  with
168       pre-npm@5.7.0  versions  of npm 5, albeit a bit more noisily. Note that
169       if package.json itself conflicts, you will have to resolve that by hand
170       and run npm install manually, even with the merge driver.
171
172   See Also
173       · https://medium.com/@sdboyer/so-you-want-to-write-a-package-man‐
174         ager-4ae9c17d9527
175
176       · npm help package.json
177
178       · npm help package-lock.json
179
180       · npm help shrinkwrap.json
181
182       · npm help shrinkwrap
183
184
185
186
187                                 February 2021                PACKAGE-LOCKS(5)
Impressum