npm lockfiles

Why lockFiles?

The input to NPM install is package.json, and its output is a node_modules tree. Ideally, NPM install should work like a pure function, always generating the exact same node_modules tree for the same package.json. In some cases, it is. But in many other cases, NPM fails to do so. For the following reasons:

  • Different versions of NPM use different installation algorithms.
  • Some dependencies may have been released since the last installation, so the dependencies will be updated according to semver-range version in package.json.
  • A dependency may have a new version released, and it will be updated even if you use the fixed dependency specifier (1.2.3 instead of ^1.2.3).

To generate the same node_modules in different environments, NPM uses package-lock.json or npm-shrinkwrap. Both files are called lockfiles. Whenever NPM install is run, NPM generates or updates lockfiles. Only package-lock.json is discussed below.

Rules for NPM I in different NPM versions

  • NPM 5.0.x version: NPM I will be downloaded according to package-lock.json regardless of whether the package.json dependencies are updated. Someone proposed issue – #16866 in response to this installation policy, which has since evolved into a post-5.1.0 rule.

  • After 5.1.0: When there is a new version of the package.json dependency, NPM install ignores package-lock.json to download the new version of the dependency and update package-lock.json. There is another issue – #17979 on this installation strategy, referring to comments by IARna, an NPM contributor, on the post-5.4.2 rules.

  • 5.4.2 After Version:

    • If there is only one package.json file, running NPM I will generate a package-lock.json file from it.

    • If the semver-range version of package.json is compatible with the package-lock.json version, even if there is a new version in package.json at this time, NPM I is also executed according to package-lock.json download – Practice Scenario 1.

    • If you manually modify the version ranges of package.json and they are incompatible with the package-lock.json version, Then package-lock.json will be updated to a package-compatible version when NPM I is executed – practice scenario 2.

practice

NPM version: 6.4.1

Scenario 1
  • Suppose a project has just been cloned from a remote repository and the local node_modules does not yet exist, package.json and package-lock.json are shown below. Given that the latest version of Superagent 3.x.x is 3.8.3, should I run NPM install to download the latest 3.x.x according to package-lock.json or according to package.json?

    // package.json
    "dependencies": {
        "superagent": "^ 3.5.1 track of"
    }
    
    // package-lock.json
    {
      "superagent": {
          "version": "3.5.1 track of"."resolved": "https://npm.garenanow.com/superagent/-/superagent-3.5.1.tgz"."integrity": "sha1-Ck+u/aM2d3d4iDR917TSH0EMhxs="."requires": {
            "component-emitter": "^ 1.2.0"."cookiejar": "^ 2.0.6"."debug": "^ 2.2.0." "."extend": "^ 3.0.0"."form-data": "^ 2.1.1"."formidable": "^ 1.1.1"."methods": "^ 1.1.1"."mime": "^" 1.3.4."qs": "^ 6.1.0"."readable-stream": "^ at 2.0.5." "}}},Copy the code

    Conclusion: 3.5.1 was downloaded. Json and package-lock.json exist at the same time. The version of package.json is ^3.5.1, and the version of package-lock.json is 3.5.1. And the current node_modules download is also 3.5.1.

Scenario 2
  • Proceed to scenario 1, and then manually change the superagent version in package.json to^ 5.1.0If node_modules is deleted or not, the superagent version in package-lock.json is changed to node_modules5.1.0node_modules5.1.0.

reference

  • npm-locks

  • Why does “npm install” rewrite package-lock.json?

  • What file is package-lock.json generated by NPM install? What’s the use?

npm ci

introduce

  • Ci: Continuous Integration.
  • The NPM version is at least V5.7.1.
  • This command is similar to NPM install, except that it is intended for use in an automated environment, such as an integration test environment, an online environment, or any situation where you want to ensure clean installation dependencies. By skipping some user-facing features, it can be much faster than regular NPM install. It is also more rigorous than a regular installation in that it can catch errors or inconsistencies caused by an incremental installation of the local environment.

NPM CI and NPM install differ

  • The project must have package-lock.json or nPM-shrinkwrap.
  • If the dependencies in lockFiles do not match those in package.json, the NPM CI will exit and report an error instead of updating the lockfiles.
  • NPM CI can install only project-wide dependencies, not individual dependencies.
  • If node_modules already exists, it will be removed automatically before the INSTALLATION of NPM CI begins.
  • NPM CI never changes package.json and package-lock.json.

supplement

  • NPM Install reads package.json to create a list of dependencies and uses package-lock.json to inform which version of these dependencies to install. If a dependency is in package.json but not package-lock.json, running NPM install updates the determined version of the dependency to package-lock.json.

  • Package. json is only used to verify whether there is A mismatched version. Suppose there is A dependency A of the determined version in package-lock.json. NPM CI will report an error if there is no dependency A in package.json or if the dependency A version is incompatible with lock.

reference

  • npm-ci

  • what-is-the-difference-between-npm-install-and-npm-ci

supplement

NPM install echarts -s to download echarts. Json. The resolved field in package-lock.json is changed to registry.npmjs.org for many other packages.

  • First query the local NPM source: NPM config get Registry

  • NPM install echarts -s; Package-lock. json is updated. Package-lock. json before and after: before and after. The main change is resolved field changed from npm.garenanow.com to registry.npmjs.org.

    Package. json (@babel/generator)

    Package. json: @babel/helper-annotate-as-pure

  • Conclusion: _resolved field specified in package.json for each package in node_modules will be copied when package-lock.json is updated, not the source specified by the current NPM. It’s likely that when you initialize the project and initially execute NPM install the source will be registry.npmjs.org, and even if you update the source later, it won’t change the _resolved field of the downloaded package. The best way to solve this problem is to create a.npmrc file in the project root directory and specify the NPM source to ensure that team members are using the same NPM source. This way, you don’t have to pull code with a lot of conflicts in package-lock.json.

Links to other articles

TypeScript trampling tour

[例 句] Build and publish a TypeScript NPM package step by step

NPM install package-lock.json update policy

Browser language preferences

Date.prototype.toLocaleString()