You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
8.4 KiB

<!doctype html>
<html>
<title>shrinkwrap</title>
<meta http-equiv="content-type" value="text/html;utf-8">
<link rel="stylesheet" type="text/css" href="../static/style.css">
<body>
<div id="wrapper">
<h1><a href="../doc/shrinkwrap.html">shrinkwrap</a></h1> <p>Lock down dependency versions</p>
<h2 id="SYNOPSIS">SYNOPSIS</h2>
<pre><code>npm shrinkwrap</code></pre>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<p>This command locks down the versions of a package&#39;s dependencies so
that you can control exactly which versions of each dependency will be
used when your package is installed. The &quot;package.json&quot; file is still
required if you want to use &quot;npm install&quot;.</p>
<p>By default, &quot;npm install&quot; recursively installs the target&#39;s
dependencies (as specified in package.json), choosing the latest
available version that satisfies the dependency&#39;s semver pattern. In
some situations, particularly when shipping software where each change
is tightly managed, it&#39;s desirable to fully specify each version of
each dependency recursively so that subsequent builds and deploys do
not inadvertently pick up newer versions of a dependency that satisfy
the semver pattern. Specifying specific semver patterns in each
dependency&#39;s package.json would facilitate this, but that&#39;s not always
possible or desirable, as when another author owns the npm package.
It&#39;s also possible to check dependencies directly into source control,
but that may be undesirable for other reasons.</p>
<p>As an example, consider package A:</p>
<pre><code>{
&quot;name&quot;: &quot;A&quot;,
&quot;version&quot;: &quot;0.1.0&quot;,
&quot;dependencies&quot;: {
&quot;B&quot;: &quot;&lt;0.1.0&quot;
}
}</code></pre>
<p>package B:</p>
<pre><code>{
&quot;name&quot;: &quot;B&quot;,
&quot;version&quot;: &quot;0.0.1&quot;,
&quot;dependencies&quot;: {
&quot;C&quot;: &quot;&lt;0.1.0&quot;
}
}</code></pre>
<p>and package C:</p>
<pre><code>{
&quot;name&quot;: &quot;C,
&quot;version&quot;: &quot;0.0.1&quot;
}</code></pre>
<p>If these are the only versions of A, B, and C available in the
registry, then a normal &quot;npm install A&quot; will install:</p>
<pre><code>A@0.1.0
`-- B@0.0.1
`-- C@0.0.1</code></pre>
<p>However, if B@0.0.2 is published, then a fresh &quot;npm install A&quot; will
install:</p>
<pre><code>A@0.1.0
`-- B@0.0.2
`-- C@0.0.1</code></pre>
<p>assuming the new version did not modify B&#39;s dependencies. Of course,
the new version of B could include a new version of C and any number
of new dependencies. If such changes are undesirable, the author of A
could specify a dependency on B@0.0.1. However, if A&#39;s author and B&#39;s
author are not the same person, there&#39;s no way for A&#39;s author to say
that he or she does not want to pull in newly published versions of C
when B hasn&#39;t changed at all.</p>
<p>In this case, A&#39;s author can run</p>
<pre><code>npm shrinkwrap</code></pre>
<p>This generates npm-shrinkwrap.json, which will look something like this:</p>
<pre><code>{
&quot;name&quot;: &quot;A&quot;,
&quot;version&quot;: &quot;0.1.0&quot;,
&quot;dependencies&quot;: {
&quot;B&quot;: {
&quot;version&quot;: &quot;0.0.1&quot;,
&quot;dependencies&quot;: {
&quot;C&quot;: {
&quot;version&quot;: &quot;0.1.0&quot;
}
}
}
}
}</code></pre>
<p>The shrinkwrap command has locked down the dependencies based on
what&#39;s currently installed in node_modules. When &quot;npm install&quot;
installs a package with a npm-shrinkwrap.json file in the package
root, the shrinkwrap file (rather than package.json files) completely
drives the installation of that package and all of its dependencies
(recursively). So now the author publishes A@0.1.0, and subsequent
installs of this package will use B@0.0.1 and C@0.1.0, regardless the
dependencies and versions listed in A&#39;s, B&#39;s, and C&#39;s package.json
files.</p>
<h3 id="Using-shrinkwrapped-packages">Using shrinkwrapped packages</h3>
<p>Using a shrinkwrapped package is no different than using any other
package: you can &quot;npm install&quot; it by hand, or add a dependency to your
package.json file and &quot;npm install&quot; it.</p>
<h3 id="Building-shrinkwrapped-packages">Building shrinkwrapped packages</h3>
<p>To shrinkwrap an existing package:</p>
<ol><li>Run &quot;npm install&quot; in the package root to install the current
versions of all dependencies.</li><li>Validate that the package works as expected with these versions.</li><li>Run &quot;npm shrinkwrap&quot;, add npm-shrinkwrap.json to git, and publish
your package.</li></ol>
<p>To add or update a dependency in a shrinkwrapped package:</p>
<ol><li>Run &quot;npm install&quot; in the package root to install the current
versions of all dependencies.</li><li>Add or update dependencies. &quot;npm install&quot; each new or updated
package individually and then update package.json. Note that they
must be explicitly named in order to be installed: running <code>npm
install</code> with no arguments will merely reproduce the existing
shrinkwrap.</li><li>Validate that the package works as expected with the new
dependencies.</li><li>Run &quot;npm shrinkwrap&quot;, commit the new npm-shrinkwrap.json, and
publish your package.</li></ol>
<p>You can use <a href="../doc/outdated.html">outdated(1)</a> to view dependencies with newer versions
available.</p>
<h3 id="Other-Notes">Other Notes</h3>
<p>A shrinkwrap file must be consistent with the package&#39;s package.json
file. &quot;npm shrinkwrap&quot; will fail if required dependencies are not
already installed, since that would result in a shrinkwrap that
wouldn&#39;t actually work. Similarly, the command will fail if there are
extraneous packages (not referenced by package.json), since that would
indicate that package.json is not correct.</p>
<p>Since &quot;npm shrinkwrap&quot; is intended to lock down your dependencies for
production use, <code>devDependencies</code> will not be included unless you
explicitly set the <code>--dev</code> flag when you run <code>npm shrinkwrap</code>. If
installed <code>devDependencies</code> are excluded, then npm will print a
warning. If you want them to be installed with your module by
default, please consider adding them to <code>dependencies</code> instead.</p>
<p>If shrinkwrapped package A depends on shrinkwrapped package B, B&#39;s
shrinkwrap will not be used as part of the installation of A. However,
because A&#39;s shrinkwrap is constructed from a valid installation of B
and recursively specifies all dependencies, the contents of B&#39;s
shrinkwrap will implicitly be included in A&#39;s shrinkwrap.</p>
<h3 id="Caveats">Caveats</h3>
<p>Shrinkwrap files only lock down package versions, not actual package
contents. While discouraged, a package author can republish an
existing version of a package, causing shrinkwrapped packages using
that version to pick up different code than they were before. If you
want to avoid any risk that a byzantine author replaces a package
you&#39;re using with code that breaks your application, you could modify
the shrinkwrap file to use git URL references rather than version
numbers so that npm always fetches all packages from git.</p>
<p>If you wish to lock down the specific bytes included in a package, for
example to have 100% confidence in being able to reproduce a
deployment or build, then you ought to check your dependencies into
source control, or pursue some other mechanism that can verify
contents rather than versions.</p>
<h2 id="SEE-ALSO">SEE ALSO</h2>
<ul><li><a href="../doc/install.html">install(1)</a></li><li><a href="../doc/json.html">json(1)</a></li><li><a href="../doc/list.html">list(1)</a></li></ul>
</div>
<p id="footer">shrinkwrap &mdash; npm@1.2.30</p>
<script>
;(function () {
var wrapper = document.getElementById("wrapper")
var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0)
.filter(function (el) {
return el.parentNode === wrapper
&& el.tagName.match(/H[1-6]/)
&& el.id
})
var l = 2
, toc = document.createElement("ul")
toc.innerHTML = els.map(function (el) {
var i = el.tagName.charAt(1)
, out = ""
while (i > l) {
out += "<ul>"
l ++
}
while (i < l) {
out += "</ul>"
l --
}
out += "<li><a href='#" + el.id + "'>" +
( el.innerText || el.text || el.innerHTML)
+ "</a>"
return out
}).join("\n")
toc.id = "toc"
document.body.appendChild(toc)
})()
</script>
</body></html>