npm install是干嘛的
npm install
命令用来安装模块到node_modules
目录。
安装之前,npm install
会先检查node_modules
目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也不会安装。
如果希望一个模块不管是否安装过,npm 都要强制重新安装,可以使用-f
或--force
参数。
1 | npm install <packageName> --force |
1 | npm install --verbose |
运行命令,会把安装过程的log输出。
registry
npm 模块仓库提供了一个查询服务,叫做 registry
,npmjs.org 的查询服务网址是https://registry.npmjs.org/
后面可以加上npm包名
,比如:https://registry.npmjs.org/npm-study4,打开地址是一个JSON 对象,里面是该模块所有版本的信息。dist.tarball
属性是该版本压缩包的网址,打开这个网址就可以下载npm压缩包,在本地解压,就可以获得源码,npm install
和npm update
命令,都是通过这种方式安装模块。
npm update
1 | npm update <packageName> |
它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。
缓存
1 | 获取目录的具体位置 |
要注意在 npm@5 之后
- 缓存数据放在
.npm/_cacache
文件夹中 - 清除命令清除的是
.npm/_cacache
目录下文件
那么看一下.npm/_cacache
目录下
在content-v2
里面基本都是一些二进制文件,把二进制文件的扩展名改为 .tgz
再解压之后,会发现就是在我们熟知的npm包。
而index-v5
里面是一些描述性的文件,也是 content-v2
里文件的索引,有点像HTTP的响应头,而且还有缓存相关的值
所以npm install
之后发生了什么
先了解一下shell的解释行(Shebang)
是什么
Shebang(也称为Hashbang)是一个由井号和叹号构成的字符串行(#!),其出现在文本文件的第一行的前两个字符。
如下列出了一些典型的shebang解释器指令:
1 | #!/bin/sh—使用sh,即Bourne shell或其它兼容shell执行脚本 |
通常出现在linux的shell脚本第一行,作为解释行,告诉解释器shell的执行方式。
在npm
入口文件后面添加--inspect-brk
就可以断点调试
1 |
入口文件在:
前置条件:npm版本6.4.1,不存在package-lock.json,以及没有缓存文件存在的情况。
1.入口文件进入
2.加载install.js
1 | function Installer (where, dryrun, args, opts) { |
1 | Installer.prototype.run = function (_cb) { |
3.经历install的生命周期
在各种生命周期中做了的一些事情:
读根目录下package.json
文件,确定依赖树
获取元信息
获取包信息,就是要安装的包的数据
内容:
下载的.tgz
后缀的压缩包,比如http://registry.npmjs.org/npm-study1/-/npm-study1-2.0.0.tgz
,保存到.npm/_cacache
文件夹,解压到node_modules
目录下,创建package-lock.json
文件。
补充:
当运行npm install
的时候,会检查node_modules
目录下,并不是node_modules
目录下有依赖包,就不安装了(情况比较多)。
如果node_modules
目录下没有这个文件,缓存里有的话,据我对打印出log的观察,应该是从缓存里解压到node_modules
目录下。
那么哪些操作会更新package.json
或更新package-lock.json
,同时更新node_modules
下的依赖包?
当node_modules
下不存在某依赖包:
npm init
初始化后,npm install xxx
(高版本的npm)会自动更新package.json
文件,并且在最后创建package-lock.json
文件,同时更新node_modules
下的依赖包。
当node_modules
下存在某依赖包:
1)^
版本号情况下, package.json
中某个依赖包的小版本要大于package-lock.json
中的同个依赖包小版本,
npm install
的时候,会修改package-lock.json
文件,同时更新node_modules
下的依赖包(安装某依赖包为当前大版本下的最新版本)。 小于的话,更新node_modules
下的某依赖包,版本号与package-lock.json
版本号一致。
2)版本号具体到某个版本的话,只要和node_modules
下的依赖包版本不同,就会安装。
2)npm update packageName
,更新package.json
文件,同时更新node_modules
下的某依赖包,版本号为当前依赖包大版本号下最新的版本(比如2.1.0就升到2.9.0,不会超过3.0.0)。
4)或者npm install xxx@x.x.x
,更新package.json
文件,更新package-lock.json
文件,更新node_modules
5)npm uninstall packageName <args>
,更新package.json
文件,更新package-lock.json
文件,更新node_modules