UNPKG

npm-jga-commonlib

Version:
181 lines (175 loc) 10.7 kB
<!doctype html> <html> <title>npm-shrinkwrap</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="../../static/style.css"> <link rel="canonical" href="https://www.npmjs.org/doc/cli/npm-shrinkwrap.html"> <script async=true src="../../static/toc.js"></script> <body> <div id="wrapper"> <h1><a href="../cli/npm-shrinkwrap.html">npm-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 <code>package.json</code> file is still required if you want to use <code>npm install</code>.</p> <p>By default, <code>npm install</code> recursively installs the target&#39;s dependencies (as specified in <code>package.json</code>), 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 <code>package.json</code> 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;, &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 <code>npm install A</code> 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 <code>npm install A</code> 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 <code>npm-shrinkwrap.json</code>, 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;from&quot;: &quot;B@^0.0.1&quot;, &quot;resolved&quot;: &quot;https://registry.npmjs.org/B/-/B-0.0.1.tgz&quot;, &quot;dependencies&quot;: { &quot;C&quot;: { &quot;version&quot;: &quot;0.0.1&quot;, &quot;from&quot;: &quot;org/C#v0.0.1&quot;, &quot;resolved&quot;: &quot;git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4&quot; } } } } } </code></pre><p>The shrinkwrap command has locked down the dependencies based on what&#39;s currently installed in <code>node_modules</code>. The installation behavior is changed to:</p> <ol> <li><p>The module tree described by the shrinkwrap is reproduced. This means reproducing the structure described in the file, using the specific files referenced in &quot;resolved&quot; if available, falling back to normal package resolution using &quot;version&quot; if one isn&#39;t.</p> </li> <li><p>The tree is walked and any missing dependencies are installed in the usual fashion.</p> </li> </ol> <p>If <code>preshrinkwrap</code>, <code>shrinkwrap</code> or <code>postshrinkwrap</code> are in the <code>scripts</code> property of the <code>package.json</code>, they will be executed by running <code>npm shrinkwrap</code>. <code>preshrinkwrap</code> and <code>shrinkwrap</code> are executed before the shrinkwrap, <code>postshrinkwrap</code> is executed afterwards. For example to run some postprocessing on the generated file:</p> <pre><code>&quot;scripts&quot;: { &quot;postshrinkwrap&quot;: &quot;node fix-shrinkwrap.js&quot; } </code></pre><h3 id="using-shrinkwrapped-packages">Using shrinkwrapped packages</h3> <p>Using a shrinkwrapped package is no different than using any other package: you can <code>npm install</code> it by hand, or add a dependency to your <code>package.json</code> file and <code>npm install</code> it.</p> <h3 id="building-shrinkwrapped-packages">Building shrinkwrapped packages</h3> <p>To shrinkwrap an existing package:</p> <ol> <li>Run <code>npm install</code> 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 <code>npm shrinkwrap</code>, add <code>npm-shrinkwrap.json</code> to git, and publish your package.</li> </ol> <p>To add or update a dependency in a shrinkwrapped package:</p> <ol> <li>Run <code>npm install</code> in the package root to install the current versions of all dependencies.</li> <li>Add or update dependencies. <code>npm install --save</code> each new or updated package individually to update the <code>package.json</code> and the shrinkwrap. 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>Commit the new <code>npm-shrinkwrap.json</code>, and publish your package.</li> </ol> <p>You can use <a href="../cli/npm-outdated.html">npm-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 <code>package.json</code> file. <code>npm shrinkwrap</code> 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 <code>package.json</code>), since that would indicate that <code>package.json</code> is not correct.</p> <p>Since <code>npm shrinkwrap</code> 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>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="../cli/npm-install.html">npm-install(1)</a></li> <li><a href="../cli/npm-run-script.html">npm-run-script(1)</a></li> <li><a href="../misc/npm-scripts.html">npm-scripts(7)</a></li> <li><a href="../files/package.json.html">package.json(5)</a></li> <li><a href="../cli/npm-ls.html">npm-ls(1)</a></li> </ul> </div> <table border=0 cellspacing=0 cellpadding=0 id=npmlogo> <tr><td style="width:180px;height:10px;background:rgb(237,127,127)" colspan=18>&nbsp;</td></tr> <tr><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)">&nbsp;</td><td style="width:40px;height:10px;background:#fff" colspan=4>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4>&nbsp;</td><td style="width:40px;height:10px;background:#fff" colspan=4>&nbsp;</td><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)">&nbsp;</td><td colspan=6 style="width:60px;height:10px;background:#fff">&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4>&nbsp;</td></tr> <tr><td colspan=2 style="width:20px;height:30px;background:#fff" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:#fff" rowspan=3>&nbsp;</td><td style="width:20px;height:10px;background:#fff" rowspan=4 colspan=2>&nbsp;</td><td style="width:10px;height:20px;background:rgb(237,127,127)" rowspan=2>&nbsp;</td><td style="width:10px;height:10px;background:#fff" rowspan=3>&nbsp;</td><td style="width:20px;height:10px;background:#fff" rowspan=3 colspan=2>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:#fff" rowspan=3>&nbsp;</td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3>&nbsp;</td></tr> <tr><td style="width:10px;height:10px;background:#fff" rowspan=2>&nbsp;</td></tr> <tr><td style="width:10px;height:10px;background:#fff">&nbsp;</td></tr> <tr><td style="width:60px;height:10px;background:rgb(237,127,127)" colspan=6>&nbsp;</td><td colspan=10 style="width:10px;height:10px;background:rgb(237,127,127)">&nbsp;</td></tr> <tr><td colspan=5 style="width:50px;height:10px;background:#fff">&nbsp;</td><td style="width:40px;height:10px;background:rgb(237,127,127)" colspan=4>&nbsp;</td><td style="width:90px;height:10px;background:#fff" colspan=9>&nbsp;</td></tr> </table> <p id="footer">npm-shrinkwrap &mdash; npm@3.10.6</p>