mirror of https://github.com/lukechilds/node.git
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.
204 lines
8.1 KiB
204 lines
8.1 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's dependencies so that you can
|
|
control exactly which versions of each dependency will be used when your package
|
|
is installed.</p>
|
|
|
|
<p>By default, "npm install" recursively installs the target's dependencies (as
|
|
specified in package.json), choosing the latest available version that satisfies
|
|
the dependency's semver pattern. In some situations, particularly when shipping
|
|
software where each change is tightly managed, it'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's
|
|
package.json would facilitate this, but that's not always possible or desirable,
|
|
as when another author owns the npm package. It'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>{
|
|
"name": "A",
|
|
"version": "0.1.0",
|
|
"dependencies": {
|
|
"B": "<0.1.0"
|
|
}
|
|
}</code></pre>
|
|
|
|
<p>package B:</p>
|
|
|
|
<pre><code>{
|
|
"name": "B",
|
|
"version": "0.0.1",
|
|
"dependencies": {
|
|
"C": "<0.1.0"
|
|
}
|
|
}</code></pre>
|
|
|
|
<p>and package C:</p>
|
|
|
|
<pre><code>{
|
|
"name": "C,
|
|
"version": "0.0.1"
|
|
}</code></pre>
|
|
|
|
<p>If these are the only versions of A, B, and C available in the registry, then
|
|
a normal "npm install A" 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 "npm install A" 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'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's author and B's author are not the same
|
|
person, there's no way for A's author to say that he or she does not want to
|
|
pull in newly published versions of C when B hasn't changed at all.</p>
|
|
|
|
<p>In this case, A'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>{
|
|
"name": "A",
|
|
"version": "0.1.0",
|
|
"dependencies": {
|
|
"B": {
|
|
"version": "0.0.1",
|
|
"dependencies": {
|
|
"C": {
|
|
"version": "0.1.0"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}</code></pre>
|
|
|
|
<p>The shrinkwrap command has locked down the dependencies based on what's
|
|
currently installed in node_modules. When "npm install" 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's, B's, and C'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 "npm install" it by hand, or add a dependency to your package.json file and
|
|
"npm install" it.</p>
|
|
|
|
<h3 id="Building-shrinkwrapped-packages">Building shrinkwrapped packages</h3>
|
|
|
|
<p>To shrinkwrap an existing package:</p>
|
|
|
|
<ol><li>Run "npm install" 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 "npm shrinkwrap", 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 "npm install" in the package root to install the current versions of all
|
|
dependencies.</li><li>Add or update dependencies. "npm install" 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 "npm shrinkwrap", 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>Since "npm shrinkwrap" uses the locally installed packages to construct the
|
|
shrinkwrap file, devDependencies will be included if and only if you've
|
|
installed them already when you make the shrinkwrap.</p>
|
|
|
|
<p>A shrinkwrap file must be consistent with the package's package.json file. "npm
|
|
shrinkwrap" will fail if required dependencies are not already installed, since
|
|
that would result in a shrinkwrap that wouldn'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>If shrinkwrapped package A depends on shrinkwrapped package B, B's shrinkwrap
|
|
will not be used as part of the installation of A. However, because A's
|
|
shrinkwrap is constructed from a valid installation of B and recursively
|
|
specifies all dependencies, the contents of B's shrinkwrap will implicitly be
|
|
included in A'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'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 — npm@1.2.11</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>
|
|
|