| <!doctype html> |
| <html> |
| <title>npm-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="../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's dependencies so |
| that you can control exactly which versions of each dependency will be |
| used when your package is installed. The "package.json" file is still |
| required if you want to use "npm install".</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="../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'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>Since "npm shrinkwrap" 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'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="../cli/npm-install.html">npm-install(1)</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> |
| <p id="footer">npm-shrinkwrap — npm@1.3.21</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> |