@@ -7,69 +7,72 @@ npm-shrinkwrap(1) -- Lock down dependency versions
77
88## DESCRIPTION
99
10- This command locks down the versions of a package's dependencies so that you can
11- control exactly which versions of each dependency will be used when your package
12- is installed. The "package.json" file is still required if you want to use "npm
13- install".
14-
15- By default, "npm install" recursively installs the target's dependencies (as
16- specified in package.json), choosing the latest available version that satisfies
17- the dependency's semver pattern. In some situations, particularly when shipping
18- software where each change is tightly managed, it's desirable to fully specify
19- each version of each dependency recursively so that subsequent builds and
20- deploys do not inadvertently pick up newer versions of a dependency that satisfy
21- the semver pattern. Specifying specific semver patterns in each dependency's
22- package.json would facilitate this, but that's not always possible or desirable,
23- as when another author owns the npm package. It's also possible to check
24- dependencies directly into source control, but that may be undesirable for other
25- reasons.
10+ This command locks down the versions of a package's dependencies so
11+ that you can control exactly which versions of each dependency will be
12+ used when your package is installed. The "package.json" file is still
13+ required if you want to use "npm install".
14+
15+ By default, "npm install" recursively installs the target's
16+ dependencies (as specified in package.json), choosing the latest
17+ available version that satisfies the dependency's semver pattern. In
18+ some situations, particularly when shipping software where each change
19+ is tightly managed, it's desirable to fully specify each version of
20+ each dependency recursively so that subsequent builds and deploys do
21+ not inadvertently pick up newer versions of a dependency that satisfy
22+ the semver pattern. Specifying specific semver patterns in each
23+ dependency's package.json would facilitate this, but that's not always
24+ possible or desirable, as when another author owns the npm package.
25+ It's also possible to check dependencies directly into source control,
26+ but that may be undesirable for other reasons.
2627
2728As an example, consider package A:
2829
2930 {
30- "name": "A",
31- "version": "0.1.0",
32- "dependencies": {
33- "B": "<0.1.0"
34- }
31+ "name": "A",
32+ "version": "0.1.0",
33+ "dependencies": {
34+ "B": "<0.1.0"
35+ }
3536 }
3637
3738package B:
3839
3940 {
40- "name": "B",
41- "version": "0.0.1",
42- "dependencies": {
43- "C": "<0.1.0"
44- }
41+ "name": "B",
42+ "version": "0.0.1",
43+ "dependencies": {
44+ "C": "<0.1.0"
45+ }
4546 }
4647
4748and package C:
4849
4950 {
50- "name": "C,
51- "version": "0.0.1"
51+ "name": "C,
52+ "version": "0.0.1"
5253 }
5354
54- If these are the only versions of A, B, and C available in the registry, then
55- a normal "npm install A" will install:
55+ If these are the only versions of A, B, and C available in the
56+ registry, then a normal "npm install A" will install:
5657
5758 A@0.1.0
5859 `-- B@0.0.1
5960 `-- C@0.0.1
6061
61- However, if B@0.0.2 is published, then a fresh "npm install A" will install:
62+ However, if B@0.0.2 is published, then a fresh "npm install A" will
63+ install:
6264
6365 A@0.1.0
6466 `-- B@0.0.2
6567 `-- C@0.0.1
6668
67- assuming the new version did not modify B's dependencies. Of course, the new
68- version of B could include a new version of C and any number of new
69- dependencies. If such changes are undesirable, the author of A could specify a
70- dependency on B@0.0.1. However, if A's author and B's author are not the same
71- person, there's no way for A's author to say that he or she does not want to
72- pull in newly published versions of C when B hasn't changed at all.
69+ assuming the new version did not modify B's dependencies. Of course,
70+ the new version of B could include a new version of C and any number
71+ of new dependencies. If such changes are undesirable, the author of A
72+ could specify a dependency on B@0.0.1. However, if A's author and B's
73+ author are not the same person, there's no way for A's author to say
74+ that he or she does not want to pull in newly published versions of C
75+ when B hasn't changed at all.
7376
7477In this case, A's author can run
7578
@@ -92,78 +95,88 @@ This generates npm-shrinkwrap.json, which will look something like this:
9295 }
9396 }
9497
95- The shrinkwrap command has locked down the dependencies based on what's
96- currently installed in node_modules. When "npm install" installs a package with
97- a npm-shrinkwrap.json file in the package root, the shrinkwrap file (rather than
98- package.json files) completely drives the installation of that package and all
99- of its dependencies (recursively). So now the author publishes A@0.1.0, and
100- subsequent installs of this package will use B@0.0.1 and C@0.1.0, regardless the
101- dependencies and versions listed in A's, B's, and C's package.json files.
98+ The shrinkwrap command has locked down the dependencies based on
99+ what's currently installed in node_modules. When "npm install"
100+ installs a package with a npm-shrinkwrap.json file in the package
101+ root, the shrinkwrap file (rather than package.json files) completely
102+ drives the installation of that package and all of its dependencies
103+ (recursively). So now the author publishes A@0.1.0, and subsequent
104+ installs of this package will use B@0.0.1 and C@0.1.0, regardless the
105+ dependencies and versions listed in A's, B's, and C's package.json
106+ files.
102107
103108
104109### Using shrinkwrapped packages
105110
106- Using a shrinkwrapped package is no different than using any other package: you
107- can "npm install" it by hand, or add a dependency to your package.json file and
108- "npm install" it.
111+ Using a shrinkwrapped package is no different than using any other
112+ package: you can "npm install" it by hand, or add a dependency to your
113+ package.json file and "npm install" it.
109114
110115### Building shrinkwrapped packages
111116
112117To shrinkwrap an existing package:
113118
114- 1 . Run "npm install" in the package root to install the current versions of all
115- dependencies.
119+ 1 . Run "npm install" in the package root to install the current
120+ versions of all dependencies.
1161212 . Validate that the package works as expected with these versions.
117- 3 . Run "npm shrinkwrap", add npm-shrinkwrap.json to git, and publish your
118- package.
122+ 3 . Run "npm shrinkwrap", add npm-shrinkwrap.json to git, and publish
123+ your package.
119124
120125To add or update a dependency in a shrinkwrapped package:
121126
122- 1 . Run "npm install" in the package root to install the current versions of all
127+ 1 . Run "npm install" in the package root to install the current
128+ versions of all dependencies.
129+ 2 . Add or update dependencies. "npm install" each new or updated
130+ package individually and then update package.json. Note that they
131+ must be explicitly named in order to be installed: running `npm
132+ install` with no arguments will merely reproduce the existing
133+ shrinkwrap.
134+ 3 . Validate that the package works as expected with the new
123135 dependencies.
124- 2 . Add or update dependencies. "npm install" each new or updated package
125- individually and then update package.json. Note that they must be
126- explicitly named in order to be installed: running ` npm install ` with
127- no arguments will merely reproduce the existing shrinkwrap.
128- 3 . Validate that the package works as expected with the new dependencies.
129- 4 . Run "npm shrinkwrap", commit the new npm-shrinkwrap.json, and publish your
130- package.
136+ 4 . Run "npm shrinkwrap", commit the new npm-shrinkwrap.json, and
137+ publish your package.
131138
132- You can use npm-outdated(1) to view dependencies with newer versions available.
139+ You can use npm-outdated(1) to view dependencies with newer versions
140+ available.
133141
134142### Other Notes
135143
136- Since "npm shrinkwrap" uses the locally installed packages to construct the
137- shrinkwrap file, devDependencies will be included if and only if you've
138- installed them already when you make the shrinkwrap.
139-
140- A shrinkwrap file must be consistent with the package's package.json file. "npm
141- shrinkwrap" will fail if required dependencies are not already installed, since
142- that would result in a shrinkwrap that wouldn't actually work. Similarly, the
143- command will fail if there are extraneous packages (not referenced by
144- package.json), since that would indicate that package.json is not correct.
145-
146- If shrinkwrapped package A depends on shrinkwrapped package B, B's shrinkwrap
147- will not be used as part of the installation of A. However, because A's
148- shrinkwrap is constructed from a valid installation of B and recursively
149- specifies all dependencies, the contents of B's shrinkwrap will implicitly be
150- included in A's shrinkwrap.
144+ A shrinkwrap file must be consistent with the package's package.json
145+ file. "npm shrinkwrap" will fail if required dependencies are not
146+ already installed, since that would result in a shrinkwrap that
147+ wouldn't actually work. Similarly, the command will fail if there are
148+ extraneous packages (not referenced by package.json), since that would
149+ indicate that package.json is not correct.
150+
151+ Since "npm shrinkwrap" is intended to lock down your dependencies for
152+ production use, ` devDependencies ` will not be included unless you
153+ explicitly set the ` --dev ` flag when you run ` npm shrinkwrap ` . If
154+ installed ` devDependencies ` are excluded, then npm will print a
155+ warning. If you want them to be installed with your module by
156+ default, please consider adding them to ` dependencies ` instead.
157+
158+ If shrinkwrapped package A depends on shrinkwrapped package B, B's
159+ shrinkwrap will not be used as part of the installation of A. However,
160+ because A's shrinkwrap is constructed from a valid installation of B
161+ and recursively specifies all dependencies, the contents of B's
162+ shrinkwrap will implicitly be included in A's shrinkwrap.
151163
152164### Caveats
153165
154- Shrinkwrap files only lock down package versions, not actual package contents.
155- While discouraged, a package author can republish an existing version of a
156- package, causing shrinkwrapped packages using that version to pick up different
157- code than they were before. If you want to avoid any risk that a byzantine
158- author replaces a package you're using with code that breaks your application,
159- you could modify the shrinkwrap file to use git URL references rather than
160- version numbers so that npm always fetches all packages from git.
166+ Shrinkwrap files only lock down package versions, not actual package
167+ contents. While discouraged, a package author can republish an
168+ existing version of a package, causing shrinkwrapped packages using
169+ that version to pick up different code than they were before. If you
170+ want to avoid any risk that a byzantine author replaces a package
171+ you're using with code that breaks your application, you could modify
172+ the shrinkwrap file to use git URL references rather than version
173+ numbers so that npm always fetches all packages from git.
161174
162175If you wish to lock down the specific bytes included in a package, for
163- example to have 100% confidence in being able to reproduce a deployment
164- or build, then you ought to check your dependencies into source control,
165- or pursue some other mechanism that can verify contents rather than
166- versions.
176+ example to have 100% confidence in being able to reproduce a
177+ deployment or build, then you ought to check your dependencies into
178+ source control, or pursue some other mechanism that can verify
179+ contents rather than versions.
167180
168181## SEE ALSO
169182
0 commit comments