npm install
1.先检查和获取 .npmrc文件的npm的配置
.npmrc示例
registry=http://npm.zhenguanyu.com/
//npm.zhenguanyu.com/:_password="xxxxx="
//npm.zhenguanyu.com/:username=xxxxx
//registry.npmjs.org/:_authToken=xxxxxx
email=xxx
auto-install-peers=true
2.检查项目中有无package-lock.json文件 有---检查lock文件与package.json中依赖是否一致 一致---使用lock文件的信息,下载资源 不一致--- 无---先构建依赖树,然后根据构建好的依赖树下载资源
下载资源时,先检查有无缓存 有缓存---直接解压到 node_modules 中 无缓存---从远端下载包,校验下载的包的完整性,添加到缓存,然后解压到 node_modules 中
最后, 生成更新后的 package-lock.json 文件
npm 构建依赖树
npm2: 递归安装,层级嵌套,每个包依赖的包装在自己的node_modules中, 缺点:可能嵌套层级很深,因此不易排查问题;有的包可能重复安装,造成冗余。
npm3:扁平结构。安装时会默认在无冲突(不重名)的前提下,尽可能将包装到更高层级;如果同名不同版本的两个包就不能装在同层级下。
npm5:增加了package-lock 文件,lock文件的结果与node_modules中是一致的。引入了缓存机制 问题:
- 1同一份lock文件,在不同时间不同环境安装时,装的结果可能是不同的;
- 2幽灵依赖:由于扁平化结构,可能导致一个包A,没有依赖B包时依然能require到B包
- 3仍有可能有大量冗余安装,如图
- 4相同的环境,不同的安装顺序,结构也可能是不同的,扁平化的提升方式不是固定的,如下图
yarn
与npm5类似,扁平化结构,使用lock文件,有缓存机制。
网络性能:yarn 采用了请求排队的理念,类似于并发池连接,能够更好的利用网络资源;同时也引入了一种安装失败的重试机制。
lock文件的结构和npm不同,不是JSON结构的。
具体的安装机制和缓存机制和npm也有所不同。
相比于npm,Yarn另一个显著的区别就是yarn.lock的子依赖的版本不是固定的版本。这其实就说明了一个问题: 一个单独的yarn.lock的问题并不能确定node-modules的文件结构,还需要package.json的配合。
pnpm
node_modules/.pnpm文件夹下平铺了所有包的所有不同版本,但全都是软连接。而node_modules文件夹下结构与package.json基本一致,非常干净。因此包不会被重复安装,相同的环境安装的结果一定是相同的。
支持 monorepo,
只在磁盘中固定位置安装包,项目中的引用实际上是硬链接而不是包文件。
安全性有所提高,解决了幽灵依赖,规避了非法访问依赖的风险。
其他:安装速度快;节省磁盘空间,尤其是对开发环境;
Monorepo 概念
就是把多个项目放在一个仓库里面,相对立的是传统的 MultiRepo 模式,即每个项目对应一个单独的仓库来分散管理。各有优缺点,
参考
npm run xxx
install 的时候生成node_modules/.bin文件夹,文件夹内有生成的软连接,相当于一种映射。
运行 npm run xxx的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx就是安装到到全局目录;
如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序。