What happens when you run the npm install command?

Abstract: When we download third-party dependencies every day, we use a command npm install, so do you know what happens when you run this command?

This article is shared from the HUAWEI CLOUD community " What happens when you run the npm install command? , by gentle_zhou.

npm (node ​​package manager) is a third-party package manager installed with Node.js; through npm, we can install, share, distribute code, and manage project dependencies.

When we download third-party dependencies every day, we use a command npm install, and then the dependency package will be installed in the node_modules directory; but what happens when we run this command? With curiosity, I went to research and study.

The general process is : npm install command input > check whether the specified dependency exists in the node_modules directory > if it already exists, do not need to reinstall it > if it does not exist, continue the following steps > to the registry (there is a corresponding .npmrc file in the local computer) Configuration address) Query the URL of the module compressed package > download the compressed package and store it in the .npm directory in the root directory > extract the compressed package to the node_modules directory of the current project.

(The above picture shows the embarrassment if there are too many dependencies in the project: the waiting time is too long, and too many dependencies are downloaded, resulting in too large node_modules)

The following will introduce the previous and current way npm handles dependencies, as well as several different ways to download the install command.

Earlier version: recursion

In earlier versions of npm, the way npm handled dependencies was crude and simple. It will recursively install dependencies into their respective node_modules directories in strict accordance with the structure of the package.json file in the root directory and the structure of the package.json file of each sub-dependency package. In this way, if it is a small project, only a few dependencies are required and these dependencies do not depend on other dependencies, then such a tree structure is quite clear (the structure of node_modules corresponds to the structure in package.json one-to-one and the hierarchical structure is obvious. ).

But if our project is a large project with many dependencies (resulting in very deep nesting levels), and different levels may reference the same dependency (resulting in duplication and redundancy), this is not what we want.

Current Version: Flattened

Therefore, in order to solve the above problems caused by recursive management dependencies, npm made an update in version 3.X and introduced the method of flat management (dedupe). Dedupe is the abbreviation of dedeplicated, that is, duplicates were removed, and the duplicates are removed.

The idea of ​​flat management is to first traverse the dependencies in the dependencies and devDependencies fields in the package.json file as the root node of the dependency tree; then, under each root node dependency, there will be its dependent dependencies as its child nodes; npm will Start multi-process from each root node and gradually search for deeper nodes. The dependencies in the dependencies and devDependencies fields in the package.json file will be installed in the node_modules root directory. When traversing these dependencies, if you find that there are duplicate dependent modules (repetition: the module name is the same and the semantic version is compatible; the compatibility here means that the semantic version will have a version allowable range, if the version numbers of the two dependencies are in This range of communication means compatibility; for example, depending on X depends on Y@^1.0.0, and depending on Z depends on Y@^1.1.0, then Y@^1.1.0 is the compatible version), just directly its discarded.

But if that's all there is to it, there's actually a risk. In a large project, it is very likely that dependency A depends on version C-1.0, and dependency B depends on version C-2.0; and when the npm install command is executed, it will follow the order of dependencies in package.json. parsed, so the order in which the dependency C-1.0 and dependency C-2.0 are placed in the file will cause the dependency structure of Node_modules to change. And in order to allow developers to use the latest dependency packages, only the major version is usually locked in the package.json file (that is, if the dependency in the file is ^1.1.0 version, npm will go to the repository to get the latest version that conforms to the 1.xx format). version), so after some minor versions of dependencies are updated, the dependency structure will also change. Therefore, in order to solve this uncertainty caused by the npm install command, the package-lock.json file has been added to the npm 5.x version.

The package-lock.json file can ensure that the node_modules directory structure generated after each execution of npm install must be exactly the same. The following figure is one of the dependency information in package-lock.json, including name-package name, version-package version number, dependencies- and the object corresponding to the package structure in node_modules, resolved-the specific installation source of the package, integrity -The hash value of the package, requires-corresponding to the dependencies of the sub-dependencies:

Note: Not all sub-dependencies have the dependencies attribute. This attribute will only exist after the dependencies of the sub-dependencies conflict with the dependencies currently installed in the Node_modules of the root directory.

Put why the package-lock.json file and the node_modules directory structure are in one-to-one correspondence. Let's take the example of the dependency conflict that just mentioned before the dependency structure changes, "dependency A depends on dependency C-1.0 version, dependency B depends on dependency C-2.0 version", at this time because the package-lock.json file If it exists, we will install the dependency C-1.0 version in the node_modules directory of the dependency A (corresponding to the dependencies attribute of the dependency A in the package.json file), and install the dependency C-2.0 version in the root directory. This ensures that the dependency directory structure generated by each installation remains the same.

The package-lock.json file also has the advantage that it will cache the specific version and download link of each package. When installing it later, there is no need to go to the remote warehouse for query operations, reducing a large number of network requests. .

Several different ways to download the install command

  1. npm install xxx # (XXX is a dependent package) Install dependent modules to the project's node_modules directory without modifying the contents of the package.json file
  2. npm install -g xxx #Install the dependent module to the global (instead of the project node_modules directory), the dependent module will not be written to the dependencies and devDependencies fields in the package.json file
  3. npm install --save xxx #Install the dependent modules to the project node_modules directory, and write the dependencies into the dependencies field in the package.json file; this dependency is required in both development and production environments
  4. npm install --save-dev xxx #Install the dependent modules to the project node_modules directory, and write the dependencies to the devDependencies field in the package.json file

 

Click Follow to learn about HUAWEI CLOUD's new technologies for the first time~

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4526289/blog/5517669