mirror of
				https://github.com/titanscouting/tra-analysis.git
				synced 2025-10-30 20:36:50 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			156 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!doctype html>
 | |
| <html>
 | |
|   <title>npm-package-locks</title>
 | |
|   <meta charset="utf-8">
 | |
|   <link rel="stylesheet" type="text/css" href="../../static/style.css">
 | |
|   <link rel="canonical" href="https://www.npmjs.org/doc/files/npm-package-locks.html">
 | |
|   <script async=true src="../../static/toc.js"></script>
 | |
| 
 | |
|   <body>
 | |
|     <div id="wrapper">
 | |
| 
 | |
| <h1><a href="../files/npm-package-locks.html">npm-package-locks</a></h1> <p>An explanation of npm lockfiles</p>
 | |
| <h2 id="description">DESCRIPTION</h2>
 | |
| <p>Conceptually, the "input" to <a href="../cli/npm-install.html">npm-install(1)</a> is a <a href="../files/package.json.html">package.json(5)</a>, while its
 | |
| "output" is a fully-formed <code>node_modules</code> tree: a representation of the
 | |
| dependencies you declared. In an ideal world, npm would work like a pure
 | |
| function: the same <code>package.json</code> should produce the exact same <code>node_modules</code>
 | |
| tree, any time. In some cases, this is indeed true. But in many others, npm is
 | |
| unable to do this. There are multiple reasons for this:</p>
 | |
| <ul>
 | |
| <li><p>different versions of npm (or other package managers) may have been used to install a package, each using slightly different installation algorithms.</p>
 | |
| </li>
 | |
| <li><p>a new version of a direct semver-range package may have been published since the last time your packages were installed, and thus a newer version will be used.</p>
 | |
| </li>
 | |
| <li><p>A dependency of one of your dependencies may have published a new version, which will update even if you used pinned dependency specifiers (<code>1.2.3</code> instead of <code>^1.2.3</code>)</p>
 | |
| </li>
 | |
| <li><p>The registry you installed from is no longer available, or allows mutation of versions (unlike the primary npm registry), and a different version of a package exists under the same version number now.</p>
 | |
| </li>
 | |
| </ul>
 | |
| <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 <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 <a href="mailto:B@0.0.2">B@0.0.2</a> 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'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 <a href="mailto:B@0.0.1">B@0.0.1</a>. 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>To prevent this potential issue, npm uses <a href="../files/package-lock.json.html">package-lock.json(5)</a> or, if present,
 | |
| n<a href="../files/pm-shrinkwrap.json.html">pm-shrinkwrap.json(5)</a>. These files are called package locks, or lockfiles.</p>
 | |
| <p>Whenever you run <code>npm install</code>, npm generates or updates your package lock,
 | |
| which will look something like this:</p>
 | |
| <pre><code>{
 | |
|   "name": "A",
 | |
|   "version": "0.1.0",
 | |
|   ...metadata fields...
 | |
|   "dependencies": {
 | |
|     "B": {
 | |
|       "version": "0.0.1",
 | |
|       "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
 | |
|       "integrity": "sha512-DeAdb33F+"
 | |
|       "dependencies": {
 | |
|         "C": {
 | |
|           "version": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }</code></pre><p>This file describes an <em>exact</em>, and more importantly <em>reproducible</em>
 | |
| <code>node_modules</code> tree. Once it's present, any future installation will base its
 | |
| work off this file, instead of recalculating dependency versions off
 | |
| p<a href="../files/ackage.json.html">ackage.json(5)</a>.</p>
 | |
| <p>The presence of a package lock changes the installation behavior such that:</p>
 | |
| <ol>
 | |
| <li><p>The module tree described by the package lock is reproduced. This means
 | |
| reproducing the structure described in the file, using the specific files
 | |
| referenced in "resolved" if available, falling back to normal package resolution
 | |
| using "version" if one isn'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 in order. <code>preshrinkwrap</code>
 | |
| and <code>shrinkwrap</code> are executed before the shrinkwrap, <code>postshrinkwrap</code> is
 | |
| executed afterwards. These scripts run for both <code>package-lock.json</code> and
 | |
| <code>npm-shrinkwrap.json</code>. For example to run some postprocessing on the generated
 | |
| file:</p>
 | |
| <pre><code>"scripts": {
 | |
|   "postshrinkwrap": "json -I -e \"this.myMetadata = $MY_APP_METADATA\""
 | |
| }</code></pre><h3 id="using-locked-packages">Using locked packages</h3>
 | |
| <p>Using a locked package is no different than using any package without a package
 | |
| lock: any commands that update <code>node_modules</code> and/or <code>package.json</code>'s
 | |
| dependencies will automatically sync the existing lockfile. This includes <code>npm
 | |
| install</code>, <code>npm rm</code>, <code>npm update</code>, etc. To prevent this update from happening,
 | |
| you can use the <code>--no-save</code> option to prevent saving altogether, or
 | |
| <code>--no-shrinkwrap</code> to allow <code>package.json</code> to be updated while leaving
 | |
| <code>package-lock.json</code> or <code>npm-shrinkwrap.json</code> intact.</p>
 | |
| <p>It is highly recommended you commit the generated package lock to source
 | |
| control: this will allow anyone else on your team, your deployments, your
 | |
| CI/continuous integration, and anyone else who runs <code>npm install</code> in your
 | |
| package source to get the exact same dependency tree that you were developing
 | |
| on. Additionally, the diffs from these changes are human-readable and will
 | |
| inform you of any changes npm has made to your <code>node_modules</code>, so you can notice
 | |
| if any transitive dependencies were updated, hoisted, etc.</p>
 | |
| <h3 id="resolving-lockfile-conflicts">Resolving lockfile conflicts</h3>
 | |
| <p>Occasionally, two separate npm install will create package locks that cause
 | |
| merge conflicts in source control systems. As of <a href="mailto:%60npm@5.7.0">`npm@5.7.0</a><code>, these conflicts
 | |
| can be resolved by manually fixing any</code>package.json<code>conflicts, and then
 | |
| running</code>npm install [--package-lock-only]<code>again. npm will automatically
 | |
| resolve any conflicts for you and write a merged package lock that includes all
 | |
| the dependencies from both branches in a reasonable tree. If</code>--package-lock-only<code>is provided, it will do this without also modifying your
 | |
| local</code>node_modules/`.</p>
 | |
| <p>To make this process seamless on git, consider installing
 | |
| <a href="https://npm.im/npm-merge-driver"><code>npm-merge-driver</code></a>, which will teach git how
 | |
| to do this itself without any user interaction. In short: <code>$ npx
 | |
| npm-merge-driver install -g</code> will let you do this, and even works with
 | |
| <a href="mailto:pre-%60npm@5.7.0">pre-`npm@5.7.0</a><code>versions of npm 5, albeit a bit more noisily. Note that if</code>package.json<code>itself conflicts, you will have to resolve that by hand and run</code>npm install` manually, even with the merge driver.</p>
 | |
| <h2 id="see-also">SEE ALSO</h2>
 | |
| <ul>
 | |
| <li><a href="https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527">https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527</a></li>
 | |
| <li><a href="../files/package.json.html">package.json(5)</a></li>
 | |
| <li><a href="../files/package-lock.json.html">package-lock.json(5)</a></li>
 | |
| <li><a href="../files/npm-shrinkwrap.json.html">npm-shrinkwrap.json(5)</a></li>
 | |
| <li><a href="../cli/npm-shrinkwrap.html">npm-shrinkwrap(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> </td></tr>
 | |
| <tr><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)"> </td><td style="width:40px;height:10px;background:#fff" colspan=4> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4> </td><td style="width:40px;height:10px;background:#fff" colspan=4> </td><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)"> </td><td colspan=6 style="width:60px;height:10px;background:#fff"> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4> </td></tr>
 | |
| <tr><td colspan=2 style="width:20px;height:30px;background:#fff" rowspan=3> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3> </td><td style="width:10px;height:10px;background:#fff" rowspan=3> </td><td style="width:20px;height:10px;background:#fff" rowspan=4 colspan=2> </td><td style="width:10px;height:20px;background:rgb(237,127,127)" rowspan=2> </td><td style="width:10px;height:10px;background:#fff" rowspan=3> </td><td style="width:20px;height:10px;background:#fff" rowspan=3 colspan=2> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3> </td><td style="width:10px;height:10px;background:#fff" rowspan=3> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3> </td></tr>
 | |
| <tr><td style="width:10px;height:10px;background:#fff" rowspan=2> </td></tr>
 | |
| <tr><td style="width:10px;height:10px;background:#fff"> </td></tr>
 | |
| <tr><td style="width:60px;height:10px;background:rgb(237,127,127)" colspan=6> </td><td colspan=10 style="width:10px;height:10px;background:rgb(237,127,127)"> </td></tr>
 | |
| <tr><td colspan=5 style="width:50px;height:10px;background:#fff"> </td><td style="width:40px;height:10px;background:rgb(237,127,127)" colspan=4> </td><td style="width:90px;height:10px;background:#fff" colspan=9> </td></tr>
 | |
| </table>
 | |
| <p id="footer">npm-package-locks — npm@6.5.0</p>
 | |
| 
 |