事情是这样子的,由于这个博客是使用 hexo + 码云的 gitee pages pro 进行搭建的,会让云端自动编译部署,其中会涉及到自动调用 npm install 这一步。由于没有对 npm install 的原理进行深入的理解,导致云端在执行 npm install 速度很慢,甚至下载失败。

包管理器(如:npm、cnpm、yarn)和依赖源(如:npmjs、淘宝源)的概念混肴

我认为包管理的功能是多样的,而依赖源就是一个很具体的地址。那么包管理器的范畴是包含依赖源的,我就在这里犯了一个认知上的错误。导致我一度认为云端编译的 npm 包管理器的依赖源只能是 npmjs ,想要转国内的淘宝源是无法做到的。

切换依赖源的方法

在切换之前你需要删除本地项目上的 package-lock.json 和 node_modules 文件与文件夹。因为依赖源的地址都记录在 package-lock.json 上,需要让 node 修改依赖源地址。详情以后会补上 npm install 的执行过程。

全局修改(不建议)

npm config set registry https://registry.npm.taobao.org

下载 cnpm 包管理器(不建议)

npm install -g cnpm

单次需改方式(推荐,其实国内的网络使用npm源都不会慢的,只是某些时候无奈只能使用淘宝源)

npm install –registry=https://registry.npm.taobao.org

npm install 的原理与执行过程 以及 node 项目下的 package.json 和 package-lock.json 区别?

一些现象:

没有 node_modules 文件夹 和 package-lock.json 文件下 用 npm i 下载依赖(为什么要这种情况下才会这样,你需要先了解 npm install 过程)

npm install 流程。如图:

解析:

看两种情况而定:有无 package-lock.json ?

1,有 lock 文件

  1. 是否和 package.json 的依赖版本是否产生冲突?若冲突则重新下载,否则到检查缓存

  2. 本地是否有缓存?特指本地的 npm-cache 文件夹里是否有 .tar 格式的包,若有则本地解压即可,没有则去registry(npm源、淘宝源)下载相关包。(地址在 package-lock.json 中的 resolved 下存在,所以 CI 在执行 npm install 时,会优先从这里找地址去下载。)

2,无 lock 文件

  1. 去npm源下载依赖

  2. 构建依赖树(用作生成 package-lock.json )。

一个依赖树大概是这个样子

├── node_modules
│   ├── A@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0
│   ├── B@1.0.0
│   │   └── node_modules
│   │   │   └── D@2.0.0
│   └── C@1.0.0
│   │   └── node_modules
│   │   │   └── D@2.0.0

如果全都安装了,我们的 node_modules 包会非常庞大,且有许多重复的依赖显得很累赘。

且依赖嵌套较深

npm 5+ 有一个扁平化安装:

结果如下:

├── node_modules
│   ├── A@1.0.0
│   │   └── node_modules
│   │   │   └── D@1.0.0
│   ├── B@1.0.0
│   ├── C@1.0.0
│   └── D@2.0.0(版本号大就保存在根目录)

可以看到,D@2.0.0模块被安装在一级node_modules中,而D@1.0.0仍被安装在A@1.0.0中。所以可以得出结论,在执行npm install安装时,如果遇到相同依赖的包,会优先将高版本(大版本)的包放在一级node_modules中,低版本的包则会按照npm 2.x的方式依次挂在依赖包的node_modules中。

  1. 由于包与包之间的依赖关系一般是很复杂的,可能好几个依赖包都有共同依赖同一个依赖库例如:lodash (可能是多个不同的版本)这就导致了 node_modules 文件夹体积很大。所以要通过扁平化的方式把 node_modules 体积减小。

ps: 如果我从 git 库中更新了 package.json 和 package-lock.json 时再 npm install 一次能否覆盖掉旧有的依赖呢?(答:可以,所以以后一旦有更新文件都应该 npm install 一次)

package.json 中的依赖,如:element-ui 版本为 2.14.1 则结果 下载的是 2.15.1 (最新版本)。这说明了 package.json 只能锁定大版本。所以这就是为什么要把 package-lock.json 文件提交到 git 仓库中。

所以就需要 package-lock.json 去精确控制版本号(且依赖树结构和 lock 文件一致,说明 lock 文件在 npm install 的时候会校验一次结构是否正确)

那么为什么 package.json 只能锁定大版本?

参考文章 https://juejin.cn/post/6844903870578032647#heading-3

  1. .npmrc 的作用

通过修改 npmrc 文件可以直接修改配置。系统中存在多个npmrc文件。

优先级从高到低的顺序为:

项目级 》项目级 》全局级 》npm内置的npmrc文件

我个人常用作统一 registry 。



npm

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!