npm 从入门到精通(二):再理解,彻底搞懂 package.json、node_modules 和 package-lock

npm 系列文章总规

《npm 从入门到精通》系列

系列目录

  1. npm 从入门到精通(一):先会用,30 分钟掌握 npm 最常用命令
  2. npm 从入门到精通(二):再理解,彻底搞懂 package.json、node_modules 和 package-lock
  3. npm 从入门到精通(三):再进阶,掌握版本管理、脚本系统与包发布
  4. npm 从入门到精通(四):再工程化,面向团队协作的 npm 最佳实践

第二篇:npm 从入门到精通(二):再理解,彻底搞懂 package.json、node_modules 和 package-lock

很多人会用 npm,但对 npm 的理解停留在:

  • npm install
  • npm run dev
  • 缺啥装啥

这没问题,但一旦项目变复杂,就会开始遇到各种疑问:

  • 为什么安装完会出现 node_modules
  • 为什么还会多一个 package-lock.json
  • 为什么团队协作中有人强调"不要删 lock 文件"?
  • dependenciesdevDependencies 到底有什么区别?

这篇文章的目标,就是把这些底层概念彻底讲清楚。


一、npm 项目的核心结构

一个最典型的 npm 项目,通常包含这些内容:

bash 复制代码
my-project/
├─ node_modules/
├─ package.json
├─ package-lock.json
└─ src/

这里最关键的是三个文件/目录:

  • package.json
  • package-lock.json
  • node_modules

它们构成了 npm 项目的基本运行机制。


二、package.json 到底是什么

package.json 是 npm 项目的核心配置文件。

它主要负责描述:

  • 项目是谁
  • 项目版本是多少
  • 入口文件是什么
  • 有哪些脚本命令
  • 依赖了哪些包

例如:

json 复制代码
{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  },
  "dependencies": {
    "react": "^19.0.0"
  },
  "devDependencies": {
    "vite": "^7.0.0"
  }
}

你可以把它理解成:

  • 项目的身份证
  • 项目的依赖清单
  • 项目的命令入口

三、dependencies 和 devDependencies 的区别

这是必须搞懂的基础。

dependencies

运行项目时必须依赖的包,例如:

  • react
  • vue
  • express
  • axios

这些属于应用运行的"正式成员"。

devDependencies

只在开发阶段需要的包,例如:

  • vite
  • webpack
  • eslint
  • typescript
  • jest

这些属于"开发辅助工具"。

最简单的判断方法

  • 项目运行时要用:dependencies
  • 只是开发、构建、测试时用:devDependencies

下面这张表更直观:

类型 作用 示例
dependencies 项目运行依赖 react、axios、express
devDependencies 开发阶段依赖 vite、eslint、typescript

四、node_modules 是什么

node_modules 是 npm 安装依赖后的实际存放目录。

当你执行:

bash 复制代码
npm install

npm 会根据 package.jsonpackage-lock.json,把需要的依赖下载到 node_modules

它的特点:

  • 体积通常很大
  • 层级结构复杂
  • 可以删除后重新安装
  • 一般不提交到 Git

所以团队项目中通常会在 .gitignore 中写:

gitignore 复制代码
node_modules/

为什么不提交?

因为:

  • 目录太大
  • 可通过配置文件重新安装
  • 不同系统下内容可能不同

五、package-lock.json 到底有什么用

这是很多人容易忽略,但又非常重要的文件。

它记录的是:

  • 实际安装的依赖精确版本
  • 每个依赖的依赖
  • 依赖树结构
  • 下载来源与校验信息

为什么需要它?

因为 package.json 通常写的是版本范围,比如:

json 复制代码
"react": "^19.0.0"

这表示允许安装 19.x.x 范围内的更新版本。

但"到底安装了哪个具体版本",就由 package-lock.json 记录。

它的价值

  • 保证团队安装结果一致
  • 保证 CI 环境安装结果一致
  • 降低"我这里能跑,你那里不行"的概率

一句话:

package.json 决定想要什么,package-lock.json 记录实际装了什么。


六、为什么不能随便删 package-lock.json

有些新手喜欢遇事就删 lock 文件,这种做法偶尔能"暂时好使",但不是长期正确习惯。

随便删除的风险

  • 团队依赖树不一致
  • 某些包被升级后出现兼容问题
  • CI / 线上构建结果变化
  • 调试难度上升

什么时候可以删?

以下场景可以考虑删除后重装:

  • 依赖树严重混乱
  • lock 文件损坏
  • 版本冲突难以修复
  • 需要彻底重建依赖环境

一般操作是:

bash 复制代码
rm -rf node_modules package-lock.json
npm install

但这属于"修复手段",不应该变成日常习惯。


七、npm install 做了什么

当你执行:

bash 复制代码
npm install

npm 并不是单纯"下载包",它实际会做这些事:

  1. 读取 package.json
  2. 读取 package-lock.json
  3. 解析依赖树
  4. 下载缺失依赖
  5. 放入 node_modules
  6. 更新 lock 文件(必要时)

所以 npm install 的本质是:

根据配置文件,构建出项目依赖环境。


八、npm ci 和 npm install 的区别

这个点非常重要,尤其到了团队协作和 CI/CD 阶段。

npm install

适合本地开发,特点是:

  • 更灵活
  • 可能会更新 lock 文件
  • 会根据 package.json 处理依赖

npm ci

适合自动化环境,特点是:

  • 严格按照 package-lock.json 安装
  • 更快
  • 更稳定
  • 如果 lock 文件和 package.json 不一致会报错

结论

  • 本地开发:常用 npm install
  • 持续集成:优先 npm ci

九、为什么别人项目拉下来就能安装

因为 npm 项目的依赖信息已经被写进:

  • package.json
  • package-lock.json

只要你把代码拉下来,再执行:

bash 复制代码
npm install

就能重建依赖环境。

这也是 npm 工程化的核心价值之一:

不需要把所有依赖文件传来传去,只需要传"依赖描述"。


十、这篇要真正记住什么

如果你只想抓住最核心的点,记住这几个:

1. package.json

记录项目信息、脚本、依赖声明

2. node_modules

依赖实际安装目录

3. package-lock.json

记录依赖精确版本和依赖树

4. 不提交 node_modules

但通常要提交 package-lock.json

5. dependenciesdevDependencies 要分清


总结

npm 真正重要的,不只是命令,而是它背后的依赖管理逻辑。

你现在需要建立的认知是:

  • package.json 是依赖声明
  • package-lock.json 是依赖锁定
  • node_modules 是依赖落地结果

理解了这三者关系,后面学版本管理、脚本系统、包发布时,就不会一头雾水。

下一篇我们进入第三层:
npm 版本号怎么管理?scripts 怎么玩?自己的包又该怎么发布?


相关推荐
用户69371750013842 小时前
XChat 为什么选择 Rust 语言开发
android·前端·ios
局i2 小时前
从零搭建 Vite + React 项目:从环境准备到干净项目的完整指南
前端·react.js·前端框架
Wect2 小时前
LeetCode 149. 直线上最多的点数:题解深度剖析
前端·算法·typescript
Wect2 小时前
JS手撕:手写Koa中间件与Promise核心特性
前端·javascript·面试
小蜜蜂dry2 小时前
nestjs实战 - 拦截器,统一处理接口请求与响应结果
前端·后端·nestjs
左右飞2 小时前
基于虚拟块高效解决不定高虚拟列表
前端
胖纳特2 小时前
业务系统深度集成:基于OnlyOffice中国版连接器实现合同生成、AI写作与报表自动化
前端·后端
MonkeyKing2 小时前
Objective-C Runtime 完整机制:objc_class /cache/bits 源码解析
前端·ios
张元清2 小时前
React 文件处理:上传、拖放区与对象 URL
前端·javascript·面试