NPM module installation mechanism:

  • Issue the NPM install command
  • Query whether the specified module already exists in the node_modules directory
    • If yes, do not reinstall it
    • If there is no
      • NPM queries Registry for the url of the module zip package
      • Download the zip package and store it in the. NPM directory under the root directory
      • Unzip the package to the node_modules directory of the current project

Implementation principle of NPM

After entering the NPM install command and pressing Enter, the following phases (NPM 5.5.1 as an example) occur:

  • The NPM project will be executed if the preinstall hook is defined.
  • The first thing you need to do is identify the first dependencies in the project, which are directly specified in the dependencies and devDependencies properties (assuming that the NPM install parameter is not added at this point).

The project itself is the root node of the whole dependency tree, and each first-level dependency module is a sub-tree below the root node. NPM will start multiple processes from each first-level dependency module to gradually find nodes at deeper levels.

  • Acquiring modules is a recursive process, which is divided into the following steps:

    • Get module information. Before downloading a module, you first need to determine its version, because package.json is often a Semantic version (semver). If nPM-shrinkwrap. Json or package-lock.json has the module information in the version description file (nPM-shrinkwrap. If the version of a package in packaeg.json is ^1.1.0, NPM will go to the repository to get the latest version in the form of 1.x.x.
    • Gets the module entity. The resolved field for the module will be obtained in the previous step. NPM will use this address to check the local cache and grab it if it is in the cache or download it from the repository if it is not. Look for the module dependency, go back to Step 1 if there are dependencies, and stop if there are none.
  • 4. Module flattening (dedupe) The previous step is to obtain a complete dependency tree, which may contain a large number of duplicate modules. For example, module A depends on loadsh and module B also depends on LoDash. Prior to NPM3, the installation was strictly based on the dependency tree structure, resulting in module redundancy.

Starting with NPM3, a dedupe process is added by default. It iterates through all nodes, placing modules one by one below the root node, the first layer of Node-modules. When duplicate modules are found, they are discarded.

Here we need a definition for duplicate modules, which means the modules have the same name and are semver-compatible. Each Semver has a set of versio-permitted ranges. If the versio-permitted ranges of two modules overlap, a compatible version can be obtained without having to have the same version number. This allows more redundant modules to be removed during dedupe.

For example, node-modules foo depends on Lodash @^1.0.0 and bar depends on lodash@^1.1.0, then ^1.1.0 is compatible.

When foo depends on LoDash @^2.0.0 and bar on LoDash @^1.1.0, semver’s rules say that no compatible version exists. One version is placed in node_modules and the other remains in the dependency tree.

For example, suppose a dependency tree would look like this:

node_modules — foo —- lodash@version1

— bar —- lodash@version2

Assuming version1 and version2 are compatible versions, dedupe will give the following form:

node_modules — foo

— bar

— Lodash (reserved version is compatible version)

Assuming version1 and version2 are incompatible, the later versions remain in the dependency tree:

node_modules — foo — lodash@version1

— bar —- lodash@version2

  • 5. Installing modules This step will update node_modules in the project and execute the life cycle functions in the module (preinstall, install, postinstall).
  • The NPM project will execute hooks if they are defined (install, postinstall, prepublish, prepare).

The last step is to generate or update the version description file, and the NPM install process is complete. Welcome criticism and praise 👍 thank you!