NPM\-SHRINKWRAP
Section: (1)
Updated: December 2016
Index
Return to Main Contents
NAME
npm-shrinkwrap - Lock down dependency versions
SYNOPSIS
-
npm shrinkwrap
DESCRIPTION
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.
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.
As an example, consider package A:
-
{
"name": "A",
"version": "0.1.0",
"dependencies": {
"B": "<0.1.0"
}
}
package B:
-
{
"name": "B",
"version": "0.0.1",
"dependencies": {
"C": "<0.1.0"
}
}
and package C:
-
{
"name": "C",
"version": "0.0.1"
}
If these are the only versions of A, B, and C available in the
registry, then a normal
npm install A will install:
-
A@0.1.0
`-- B@0.0.1
`-- C@0.0.1
However, if B@0.0.2 is published, then a fresh
npm install A will
install:
-
A@0.1.0
`-- B@0.0.2
`-- C@0.0.1
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.
In this case, A's author can run
-
npm shrinkwrap
This generates
npm-shrinkwrap.json, which will look something like this:
-
{
"name": "A",
"version": "0.1.0",
"dependencies": {
"B": {
"version": "0.0.1",
"from": "B@^0.0.1",
"resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
"dependencies": {
"C": {
"version": "0.0.1",
"from": "org/C#v0.0.1",
"resolved": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
}
}
}
}
}
The shrinkwrap command has locked down the dependencies based on what's
currently installed in
node_modules. The installation behavior is changed to:
-
- 1.
-
The module tree described by the shrinkwrap 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.
- 2.
-
The tree is walked and any missing dependencies are installed in the usual fashion.
If
preshrinkwrap,
shrinkwrap or
postshrinkwrap are in the
scripts property of the
package.json, they will be executed by running
npm shrinkwrap.
preshrinkwrap and
shrinkwrap are executed before the shrinkwrap,
postshrinkwrap is
executed afterwards. For example to run some postprocessing on the generated file:
-
"scripts": { "postshrinkwrap": "node fix-shrinkwrap.js" }
Using shrinkwrapped packages
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.
Building shrinkwrapped packages
To shrinkwrap an existing package:
-
- 1.
-
Run npm install in the package root to install the current
versions of all dependencies.
- 2.
-
Validate that the package works as expected with these versions.
- 3.
-
Run npm shrinkwrap, add npm-shrinkwrap.json to git, and publish
your package.
To add or update a dependency in a shrinkwrapped package:
-
- 1.
-
Run npm install in the package root to install the current
versions of all dependencies.
- 2.
-
Add or update dependencies. npm install --save or npm install --save-dev
each new or updated package individually to update the package.json and
the shrinkwrap. Note that they must be explicitly named in order to be
installed: running npm install with no arguments will merely reproduce
the existing shrinkwrap.
- 3.
-
Validate that the package works as expected with the new
dependencies.
- 4.
-
Commit the new npm-shrinkwrap.json, and publish your package.
You can use npm help outdated to view dependencies with newer versions
available.
Other Notes
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.
Starting with npm v4.0.1,
devDependencies are included when you run
npm shrinkwrap and follow the usual rules as to when they're installed.
As of npm v3.10.8, if you run
npm install --only=production or
npm install --production with a shrinkwrap including your development
dependencies they won't be installed. Similarly, if the environment
variable
NODE_ENV is
production then they won't be installed. If you
need compatibility with versions of npm prior to v3.10.8 or otherwise
don't want them in your shrinkwrap you can exclude development
dependencies with:
npm shrinkwrap --only=prod or
npm shrinkwrap --production.
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.
Caveats
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.
SEE ALSO
-
- *
-
npm help install
- *
-
npm help run-script
- *
-
npm help 7 scripts
- *
-
npm help 5 package.json
- *
-
npm help ls
Index
- NAME
-
- SYNOPSIS
-
- DESCRIPTION
-
- Using shrinkwrapped packages
-
- Building shrinkwrapped packages
-
- Other Notes
-
- Caveats
-
- SEE ALSO
-