package.json是依赖声明的法定总账本,lock file才是安装时真正执行的精确清单;前者定义版本范围(如^4.17.21),后者锁定具体版本、地址与校验值,二者协同保障跨环境一致性与协作稳定性。

直接画核心知识点思维导图,不用先搭环境、不堆工具链,聚焦“真正影响项目稳定性和协作效率”的关键点。重点不是命令罗列,而是理解依赖怎么来、怎么存、怎么查、怎么控。
一、package.json 是依赖的总账本
它不是配置文件,是项目依赖关系的法定声明:
-
dependencies:运行时必需的包(如
express、axios),上线必须存在 -
devDependencies:仅开发阶段需要(如
eslint、vite),打包构建后不参与运行 -
peerDependencies:声明“我期望宿主环境提供什么”,常见于插件类包(如
vue-loader要求宿主有vue);npm 7+ 会自动校验,不满足会报ERESOLVE - 版本号写法决定行为:
"lodash": "^4.17.21"允许补丁和次版本升级,"lodash": "~4.17.21"只允许补丁升级,"lodash": "4.17.21"锁死精确版本
二、node_modules 是逻辑树,不是文件夹列表
别只看目录结构,要理解 npm 安装时的真实依赖关系:
- 执行
npm ls打印出完整的依赖树,带缩进和颜色标记(红色表示缺失或冲突,橙色表示被 dedupe 提升到顶层) - 重复依赖 ≠ 错误,但可能是隐患:两个子包分别依赖
moment@2.29.4和moment@3.0.0,npm 会保留两份,增大体积且可能引发运行时冲突 - 幽灵依赖很危险:某模块没在
package.json中声明,却因提升出现在node_modules顶层,代码里直接require('xxx')能跑通——但上游一升级就断,且无提示
三、安装与更新必须配合 lock 文件
package-lock.json 不是可选文件,是团队一致性的强制保障:
- 它记录了每个包的确切版本、完整下载地址、完整性哈希(integrity),确保
npm install在任何机器上还原出完全相同的依赖树 - 不要手动改 lock 文件,也不要忽略它;CI/CD 流程中必须提交并校验
- 升级依赖推荐用
npm update或npm install,而非直接改@latest package.json后删node_modules—— 后者容易跳过 lock 校验,引入不一致
四、排查问题靠树,不是靠猜
遇到“找不到模块”“版本冲突”“安装失败”,立刻用这几条命令定位根源:
-
npm ls:查某个包在树中的所有位置和版本,确认是否被多个路径引入 -
npm ls --depth=0:只看顶层直接依赖,快速核对package.json是否漏写 -
npm explain(npm v8.3+):显示“为什么这个包被安装”,包括谁请求了它、版本约束来自哪一行 -
npm audit:检查已安装依赖是否存在已知安全漏洞,npm audit fix尝试自动修复











