diff options
Diffstat (limited to 'docs/content/configuring-npm/package-lock-json.md')
-rw-r--r-- | docs/content/configuring-npm/package-lock-json.md | 257 |
1 files changed, 174 insertions, 83 deletions
diff --git a/docs/content/configuring-npm/package-lock-json.md b/docs/content/configuring-npm/package-lock-json.md index a3083410f..4d994bbc8 100644 --- a/docs/content/configuring-npm/package-lock-json.md +++ b/docs/content/configuring-npm/package-lock-json.md @@ -14,132 +14,223 @@ generate identical trees, regardless of intermediate dependency updates. This file is intended to be committed into source repositories, and serves various purposes: -* Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies. +* Describe a single representation of a dependency tree such that + teammates, deployments, and continuous integration are guaranteed to + install exactly the same dependencies. -* Provide a facility for users to "time-travel" to previous states of `node_modules` without having to commit the directory itself. +* Provide a facility for users to "time-travel" to previous states of + `node_modules` without having to commit the directory itself. -* To facilitate greater visibility of tree changes through readable source control diffs. +* Facilitate greater visibility of tree changes through readable source + control diffs. -* And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages. +* Optimize the installation process by allowing npm to skip repeated + metadata resolutions for previously-installed packages. -One key detail about `package-lock.json` is that it cannot be published, and it -will be ignored if found in any place other than the toplevel package. It shares -a format with [npm-shrinkwrap.json](/configuring-npm/shrinkwrap-json), which is essentially the same file, but -allows publication. This is not recommended unless deploying a CLI tool or -otherwise using the publication process for producing production packages. +* As of npm v7, lockfiles include enough information to gain a complete + picture of the package tree, reducing the need to read `package.json` + files, and allowing for significant performance improvements. -If both `package-lock.json` and `npm-shrinkwrap.json` are present in the root of -a package, `package-lock.json` will be completely ignored. +### `package-lock.json` vs `npm-shrinkwrap.json` +Both of these files have the same format, and perform similar functions in +the root of a project. -### File Format +The difference is that `package-lock.json` is that it cannot be published, +and it will be ignored if found in any place other than the root project. -#### name +In contrast, [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) allows +publication, and defines the dependency tree from the point encountered. +This is not recommended unless deploying a CLI tool or otherwise using the +publication process for producing production packages. -The name of the package this is a package-lock for. This must match what's in -`package.json`. +If both `package-lock.json` and `npm-shrinkwrap.json` are present in the +root of a project, `npm-shrinkwrap.json` will take precedence and +`package-lock.json` will be ignored. -#### version +### Hidden Lockfiles -The version of the package this is a package-lock for. This must match what's in -`package.json`. +In order to avoid processing the `node_modules` folder repeatedly, npm as +of v7 uses a "hidden" lockfile present in +`node_modules/.package-lock.json`. This contains information about the +tree, and is used in lieu of reading the entire `node_modules` hierarchy +provided that the following conditions are met: -#### lockfileVersion +- All package folders it references exist in the `node_modules` hierarchy. +- No package folders exist in the `node_modules` hierarchy that are not + listed in the lockfile. +- The modified time of the file is at least as recent as all of the package + folders it references. -An integer version, starting at `1` with the version number of this document -whose semantics were used when generating this `package-lock.json`. +That is, the hidden lockfile will only be relevant if it was created as +part of the most recent update to the package tree. If another CLI mutates +the tree in any way, this will be detected, and the hidden lockfile will be +ignored. -#### packageIntegrity +Note that it _is_ possible to manually change the _contents_ of a package +in such a way that the modified time of the package folder is unaffected. +For example, if you add a file to `node_modules/foo/lib/bar.js`, then the +modified time on `node_modules/foo` will not reflect this change. If you +are manually editing files in `node_modules`, it is generally best to +delete the file at `node_modules/.package-lock.json`. -This is a [subresource -integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) value -created from the `package.json`. No preprocessing of the `package.json` should -be done. Subresource integrity strings can be produced by modules like -[`ssri`](https://www.npmjs.com/package/ssri). +As the hidden lockfile is ignored by older npm versions, it does not +contain the backwards compatibility affordances present in "normal" +lockfiles. That is, it is `lockfileVersion: 3`, rather than +`lockfileVersion: 2`. -#### preserveSymlinks +### Handling Old Lockfiles -Indicates that the install was done with the environment variable -`NODE_PRESERVE_SYMLINKS` enabled. The installer should insist that the value of -this property match that environment variable. +When npm detects a lockfile from npm v6 or before during the package +installation process, it is automatically updated to fetch missing +information from either the `node_modules` tree or (in the case of empty +`node_modules` trees or very old lockfile formats) the npm registry. -#### dependencies +### File Format -A mapping of package name to dependency object. Dependency objects have the -following properties: +#### `name` -##### version +The name of the package this is a package-lock for. This will match what's +in `package.json`. -This is a specifier that uniquely identifies this package and should be -usable in fetching a new copy of it. +#### `version` -* bundled dependencies: Regardless of source, this is a version number that is purely for informational purposes. -* registry sources: This is a version number. (eg, `1.2.3`) -* git sources: This is a git specifier with resolved committish. (eg, `git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e`) -* http tarball sources: This is the URL of the tarball. (eg, `https://example.com/example-1.3.0.tgz`) -* local tarball sources: This is the file URL of the tarball. (eg `file:///opt/storage/example-1.3.0.tgz`) -* local link sources: This is the file URL of the link. (eg `file:libs/our-module`) +The version of the package this is a package-lock for. This will match +what's in `package.json`. -##### integrity +#### `lockfileVersion` -This is a [Standard Subresource -Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) for this -resource. +An integer version, starting at `1` with the version number of this +document whose semantics were used when generating this +`package-lock.json`. -* For bundled dependencies this is not included, regardless of source. -* For registry sources, this is the `integrity` that the registry provided, or if one wasn't provided the SHA1 in `shasum`. -* For git sources this is the specific commit hash we cloned from. -* For remote tarball sources this is an integrity based on a SHA512 of - the file. -* For local tarball sources: This is an integrity field based on the SHA512 of the file. +Note that the file format changed significantly in npm v7 to track +information that would have otherwise required looking in `node_modules` or +the npm registry. Lockfiles generated by npm v7 will contain +`lockfileVersion: 2`. -##### resolved +* No version provided: an "ancient" shrinkwrap file from a version of npm + prior to npm v5. +* `1`: The lockfile version used by npm v5 and v6. +* `2`: The lockfile version used by npm v7, which is backwards compatible + to v1 lockfiles. +* `3`: The lockfile version used by npm v7, _without_ backwards + compatibility affordances. This is used for the hidden lockfile at + `node_modules/.package-lock.json`, and will likely be used in a future + version of npm, once support for npm v6 is no longer relevant. -* For bundled dependencies this is not included, regardless of source. -* For registry sources this is path of the tarball relative to the registry - URL. If the tarball URL isn't on the same server as the registry URL then - this is a complete URL. +npm will always attempt to get whatever data it can out of a lockfile, even +if it is not a version that it was designed to support. -##### bundled +#### `packages` -If true, this is the bundled dependency and will be installed by the parent -module. When installing, this module will be extracted from the parent -module during the extract phase, not installed as a separate dependency. +This is an object that maps package locations to an object containing the +information about that package. -##### dev +The root project is typically listed with a key of `""`, and all other +packages are listed with their relative paths from the root project folder. -If true then this dependency is either a development dependency ONLY of the -top level module or a transitive dependency of one. This is false for -dependencies that are both a development dependency of the top level and a -transitive dependency of a non-development dependency of the top level. +Package descriptors have the following fields: -##### optional +* version: The version found in `package.json` -If true then this dependency is either an optional dependency ONLY of the -top level module or a transitive dependency of one. This is false for -dependencies that are both an optional dependency of the top level and a -transitive dependency of a non-optional dependency of the top level. +* resolved: The place where the package was actually resolved from. In + the case of packages fetched from the registry, this will be a url to a + tarball. In the case of git dependencies, this will be the full git url + with commit sha. In the case of link dependencies, this will be the + location of the link target. -All optional dependencies should be included even if they're uninstallable -on the current platform. +* integrity: A `sha512` or `sha1` [Standard Subresource + Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) + string for the artifact that was unpacked in this location. +* link: A flag to indicate that this is a symbolic link. If this is + present, no other fields are specified, since the link target will also + be included in the lockfile. -##### requires +* dev, optional, devOptional: If the package is strictly part of the + `devDependencies` tree, then `dev` will be true. If it is strictly part + of the `optionalDependencies` tree, then `optional` will be set. If it + is both a `dev` dependency _and_ an `optional` dependency of a non-dev + dependency, then `devOptional` will be set. (An `optional` dependency of + a `dev` dependency will have both `dev` and `optional` set.) -This is a mapping of module name to version. This is a list of everything -this module requires, regardless of where it will be installed. The version -should match via normal matching rules a dependency either in our -`dependencies` or in a level higher than us. +* inBundle: A flag to indicate that the package is a bundled dependency. +* hasInstallScript: A flag to indicate that the package has a `preinstall`, + `install`, or `postinstall` script. -##### dependencies +* hasShrinkwrap: A flag to indicate that the package has an + `npm-shrinkwrap.json` file. + +* bin, license, engines, dependencies, optionalDependencies: fields from + `package.json` + +#### dependencies -The dependencies of this dependency, exactly as at the top level. +Legacy data for supporting versions of npm that use `lockfileVersion: 1`. +This is a mapping of package names to dependency objects. Because the +object structure is strictly hierarchical, symbolic link dependencies are +somewhat challenging to represent in some cases. + +npm v7 ignores this section entirely if a `packages` section is present, +but does keep it up to date in order to support switching between npm v6 +and npm v7. + +Dependency objects have the following fields: + +* version: a specifier that varies depending on the nature of the package, + and is usable in fetching a new copy of it. + + * bundled dependencies: Regardless of source, this is a version number + that is purely for informational purposes. + * registry sources: This is a version number. (eg, `1.2.3`) + * git sources: This is a git specifier with resolved committish. (eg, + `git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e`) + * http tarball sources: This is the URL of the tarball. (eg, + `https://example.com/example-1.3.0.tgz`) + * local tarball sources: This is the file URL of the tarball. (eg + `file:///opt/storage/example-1.3.0.tgz`) + * local link sources: This is the file URL of the link. (eg + `file:libs/our-module`) + +* integrity: A `sha512` or `sha1` [Standard Subresource + Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) + string for the artifact that was unpacked in this location. For git + dependencies, this is the commit sha. + +* resolved: For registry sources this is path of the tarball relative to + the registry URL. If the tarball URL isn't on the same server as the + registry URL then this is a complete URL. + +* bundled: If true, this is the bundled dependency and will be installed + by the parent module. When installing, this module will be extracted + from the parent module during the extract phase, not installed as a + separate dependency. + +* dev: If true then this dependency is either a development dependency ONLY + of the top level module or a transitive dependency of one. This is false + for dependencies that are both a development dependency of the top level + and a transitive dependency of a non-development dependency of the top + level. + +* optional: If true then this dependency is either an optional dependency + ONLY of the top level module or a transitive dependency of one. This is + false for dependencies that are both an optional dependency of the top + level and a transitive dependency of a non-optional dependency of the top + level. + +* requires: This is a mapping of module name to version. This is a list of + everything this module requires, regardless of where it will be + installed. The version should match via normal matching rules a + dependency either in our `dependencies` or in a level higher than us. + +* dependencies: The dependencies of this dependency, exactly as at the top + level. ### See also * [npm shrinkwrap](/commands/npm-shrinkwrap) -* [shrinkwrap.json](/configuring-npm/shrinkwrap-json) -* [package-locks](/configuring-npm/package-locks) +* [npm-shrinkwrap.json](/configuring-npm/npm-shrinkwrap-json) * [package.json](/configuring-npm/package-json) * [npm install](/commands/npm-install) |