一、准备阶段:配置与环境检查
读取配置优先级
npm install首先加载多层级的配置(优先级从高到低)4:项目级
.npmrc用户级
.npmrc(如~/.npmrc)全局
npmrcnpm 内置默认配置
可通过npm config ls -l查看所有配置。
检查锁定文件
若存在
package-lock.json:
对比其与package.json的依赖版本是否一致:✅ 一致 → 直接使用锁定文件中的依赖树。
❌ 不一致 → 按 npm 版本策略处理(如 npm 5.x+ 会以
package.json为准更新锁定文件)4。
若无锁定文件 → 根据
package.json递归构建依赖树4。
二、依赖解析阶段:构建依赖树与扁平化
依赖树生成
npm 解析package.json中的dependencies和devDependencies,递归收集所有子依赖,形成树状结构4。扁平化处理(Deduplication)
将依赖按相同版本提升到
node_modules根目录(如react只安装一份)。若版本冲突(如 A 依赖
lodash@^4.0,B 依赖lodash@^3.0)→ 在 B 的node_modules下单独安装lodash@3.x4。
三、安装阶段:缓存与下载
缓存查询
每个包根据
name@version生成唯一 Key,在缓存目录(npm config get cache,通常为_cacache)中查找14。若缓存命中且校验通过(通过
integrity字段验证完整性)→ 直接解压到项目node_modules。
远程下载
若缓存未命中 → 从 npm 仓库(或配置的镜像如淘宝源)下载包。
下载后:
校验完整性(SHA 摘要)。
存入缓存。
解压至
node_modules14。
📦 四、收尾阶段:写入与清理
生成/更新
package-lock.json
记录所有依赖的精确版本、下载地址、依赖树结构,确保后续安装一致4。运行生命周期脚本
按顺序执行包中定义的脚本(如preinstall、postinstall),某些包可能在此阶段编译原生模块。
⚠️ 五、常见问题与解决
| 问题场景 | 原因与解决方案 |
|---|---|
| 安装后报错“模块找不到” | 缓存损坏或网络中断导致包不完整 → 清除缓存重试:npm cache clean --force + 删除 node_modules 重装14。 |
node_modules 无法删除 | 文件被进程占用 → 关闭 IDE(如 VSCode)或使用命令行强制删除12。 |
| 安全漏洞警告 | 运行 npm audit 查看漏洞详情 → 使用 npm audit fix 自动修复,或手动升级受影响包7。 |
| Linux 系统权限灾难 | ⚠️ 历史教训:npm v5.7.0 在 sudo 下运行时递归修改系统目录所有权(如 /etc),导致系统崩溃 → 永远避免用 sudo 执行 npm!356。 |
💎 关键机制总结
缓存优化:显著加速重复安装,但需注意缓存污染问题4。
锁定文件作用:确保跨环境安装一致性,务必提交到版本控制。
安全审计:
npm audit主动检测依赖链漏洞(如react-native-validator-form案例中的 Karma 漏洞)7
流程图
