Introduction to npm module installation mechanism

npm  is Node's module manager and is extremely powerful. It's one of the big reasons for Node's success.

Thanks to npm, we can install modules written by others with just one line of command.


$ npm install 

This article describes the details of the npm module installation mechanism and how to solve the slow installation problem.

1. Start with npm install

npm install The command is used to install the module into the node_modulesdirectory.


$ npm install <packageName>

Before installation, npm installit will first check node_moduleswhether the specified module already exists in the directory. If it exists, there is no reinstallation, even if the remote repo already has a new version.

If you want npm to force a module to be reinstalled regardless of whether it was installed or not, you can use the -for --forceparameter.


$ npm install <packageName> --force

二、npm update

If you want to update installed modules, you need to use npm updatethe command.


$ npm update <packageName>

It will first go to the remote repository to query the latest version, and then query the local version. If the local version does not exist, or the remote version is newer, it will be installed.

Third, registry

npm updateHow does the command know the latest version of each module?

The answer is that the npm module repository provides a query service called registry. Take npmjs.org as an example, its query service URL is  https://registry.npmjs.org/ .

Follow this URL with the module name and you will get a JSON object with information about all versions of the module. For example, if you visit  https://registry.npmjs.org/react, you will see information about all versions of the react module.

It has the same effect as the following command.


$ npm view react

# npm view 的别名
$ npm info react
$ npm show react
$ npm v react

After the module name of the registry URL, you can also follow the version number or label to query the information of a specific version. For example, visit https://registry.npmjs.org/react/v0.14.6 to see version 0.14.6 of React.

In the returned JSON object, there is an dist.tarballattribute, which is the URL of the compressed package of this version.


dist: {
  shasum: '2a57c2cf8747b483759ad8de0fa47fb0c5cf5c6a',
  tarball: 'http://registry.npmjs.org/react/-/react-0.14.6.tgz' 
},

Go to this website to download the compressed package, decompress it locally, and get the source code of the module. npm installand npm updatecommands, all install modules in this way.

Fourth, the cache directory

npm installOr npm updatecommand, after downloading the compressed package from the registry, it is stored in the local cache directory.

This cache directory, which defaults to the user's home directory on Linux or Mac .npm, is the default on Windows %AppData%/npm-cache. Through the configuration command, you can view the specific location of this directory.


$ npm config get cache
$HOME/.npm

You'd better browse this directory.


$ ls ~/.npm 
# 或者
$ npm cache ls

You will see a large number of modules are stored inside, the storage structure is {cache}/{name}/{version}.


$ npm cache ls react
~/.npm/react/react/0.14.6/
~/.npm/react/react/0.14.6/package.tgz
~/.npm/react/react/0.14.6/package/
~/.npm/react/react/0.14.6/package/package.json

Each version of each module has its own subdirectory containing the code zip package.tgzfile and a description file package/package.json.

In addition to that, a {cache}/{hostname}/{path}/.cache.jsonfile is generated. For example, when you download a react module from the official npm repository, a registry.npmjs.org/react/.cache.jsonfile is generated.

This file saves all version information, as well as the last modification time of the module and the ETag returned by the server during the latest request.


{
  "time":{
    "modified":"2016-01-06T23:52:45.571Z",
    // ...
  },
  "_etag":"\"7S37I0775YLURCFIO8N85FO0F\""
}

For some operations that are not very critical (such as npm searchor npm view), npm will first check .cache.jsonthe latest update time of the module in it, and whether the gap with the current time is within an acceptable range. If it is, it will no longer make a request to the remote warehouse, but return .cache.jsonthe data directly.

.npmThe directory holds a large number of files, and the command to clear it is as follows.


$ rm -rf ~/.npm/*
# 或者
$ npm cache clean

Five, the module installation process

To sum up, the installation process of Node modules is like this.

  1. issue an npm installorder
  2. npm queries the registry for the URL of the module compressed package
  3. Download the compressed package and store it in the ~/.npmdirectory
  4. Unzip the archive to the node_modulesdirectory of the current project

Note that after a module is installed, two copies are actually saved locally. One is ~/.npmthe compressed package in the directory, and the other is node_modulesthe decompressed code in the directory.

However, npm installwhen running, only the node_modulesdirectory is checked, not the ~/.npmdirectory. That is, if a ~/.npmmodule has a tarball under it, but it's not installed in the node_modulesdirectory, npm will still download a new tarball from the remote repository.

This behavior certainly guarantees that the latest code is always available, but sometimes it is not what we want. The biggest problem is that it greatly affects the installation speed. Even if the compressed package of a module is in the cache directory, it must be downloaded from the remote warehouse. How can it not be slow?

In addition, in some occasions there is no network (such as on an airplane), but the module you want to install is obviously in the cache directory, and it cannot be installed at this time.

6. --cache-min Parameters

To address these issues, npm provides an --cache-minargument for installing modules from a cache directory.

--cache-minThe parameter specifies a time (in minutes), and only modules that exceed this time will be downloaded from the registry.


$ npm install --cache-min 9999999 <package-name>

The above command specifies that only modules older than 999999 minutes are downloaded from the registry. In fact, it is specified that all modules are installed from the cache, which greatly speeds up the download speed.

It has another way of writing it.


$ npm install --cache-min Infinity <package-name>

However, this does not equate to offline mode, where an internet connection is still required . Because the current --cache-minimplementation has some problems.

(1) If the specified module is not in the cache directory, npm will connect to the registry and download the latest version. This is no problem, but if the specified module is in the cache directory, npm will also connect to the registry , issue the etag of the specified module, and the server returns a status code of 304, indicating that the compressed package does not need to be downloaded again.

(2) If a module is already in the cache, but the version is lower than required, npm will report an error directly instead of going to the registry to download the latest version.

The npm team is aware of these issues and is rewriting the cache . And, in the future, a --offlineparameter will be provided to make npm available offline.

However, there is no schedule for these improvements. Therefore, the current use of --cache-minimproving the installation speed is problematic.

Seven, offline installation solutions

The community has proposed several solutions for offline use of npm. They can greatly speed up module installation.

Solutions fall broadly into three categories.

The first category, the Registry proxy.

The usage of the above three modules is very similar. They all start a Registry service on the machine, and all npm installcommands must be proxied by this service.


# npm-proxy-cache
$ npm --proxy http://localhost:8080 \
  --https-proxy http://localhost:8080 \
  --strict-ssl false \
  install

# local-npm
$ npm set registry http://127.0.0.1:5080

# npm-lazy
$ npm --registry http://localhost:8080/ install socket.io

With the local registry service, the cache installation can be completely realized and offline use can be realized.

The second category is npm installsubstitution.

If you can change npm installthe behavior, you can achieve cache installation. npm-cache Tools are this idea. Substitutes can be used npm installwherever they are used .npm-cache


$ npm-cache install

The third category, node_modulesas a cache directory.

The idea of ​​​​this scheme is to not use the .npmcache, but to use the project's node_modulesdirectory as the cache.

The above two tools can make the node_modulesdirectory of the project into a compressed package, and then extract the files from this compressed package when installing it later.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325207175&siteId=291194637