剖析npm的包管理机制

704 阅读2分钟

一、包管理

1、npm会把项目中的多层嵌套的依赖包打平存放到node_module一级目录下,以减少相同依赖包的下载和存储消耗。

例如:
我们新建一个react项目npmdemo,依赖包的嵌套关系结构如图:

执行npm innstall命令,我们打开node_module目录,看到依赖包都被打平到node_module目录下了:

2、lock文件功能

有的同学可能会问了:依赖包都打平到node_module目录下的话,如果项目中出现不同版本的依赖包,npm又怎么处理呢?

**当依赖包版本不同,npm会按照package-lock.json文件的路径层次结构处理依赖包**,比如,项目中同时依赖js-tokens@4.0.0和js-tokens@6.0.0两个包,会按照package-lock.json里的目录结构处理依赖包。避免因包版本不同造成覆盖进而导致兼容问题。
package-lock.json文件中存储依赖包的相关信息:
"@babel/code-frame": {
    "version": "7.0.0",
    "resolved": "http://registry.npm.taobao.org/@babel/code-frame/download/@babel/code-frame-7.0.0.tgz",
    "integrity": "sha1-BuKrGb21NThVWaq7W6WXKUgoAPg=",
    "dev": true,
    "requires": {
    "@babel/highlight": "^7.0.0"
    }
},
  • version 标记当前依赖包的版本号
  • resolved 字段存储npm包的下载地址
  • integrity 字段是npm安装的缓存地址
因此,项目中的**package-lock.json文件一定要上传到远程仓库**。可以使得 npm install 命令安装的依赖包目录结构保持一致,避免开发中的因依赖包版本、路径不同而出现问题。同时可以提高 npm install 的安装速度。

二、缓存管理

npm install或npm update命令,从 registry 下载压缩包之后,都存放在本地的缓存目录。这个缓存目录,在 Linux 或 Mac 默认是用户主目录下的.npm目录。
npm将包缓存在_cacache目录下,npm5版本之后,_cacache目录下新增了两个文件夹存储包,分别是content-v2和index-v5,两个目录的文件结构分别是:

这两个目录下存储了npm包文件,在package-lock.json文件中的integrity字段存储缓存文件的路径。每次npm install时,会优先查看是否有缓存,如果有从缓存中取,否则通过resolved字段值去下载npm包。npm下载安装流程如下图:

参考文章:

npm install原理