NPM

package.json 完全指南

掌握 package.json 的核心字段,理解 dependencies、devDependencies、scripts 和 engines 的用途与区别。

🎯 引言

学会这篇文章,你将彻底看懂 package.json 这个文件。它不只是项目的“身份证”,更是管理依赖、脚本、环境约束的核心配置文件。掌握它,你在接手任何项目时都能快速上手。


🧱 package.json 是什么

package.json 是每个 NPM 项目的核心配置文件,通常放在项目根目录。它主要做三件事:

  1. 描述项目:名字、版本、作者、许可证等。
  2. 管理依赖:记录项目需要哪些第三方包,以及版本要求。
  3. 定义脚本:把常用命令封装成 npm run xxx 这样的简短指令。
可以把 package.json 理解为项目的“菜单”。别人拿到项目后,看一眼菜单就知道需要准备哪些“食材”(依赖),以及怎么“烹饪”(运行脚本)。

📋 常用字段详解

name 和 version

package.json
{
    "name": "my-project",
    "version": "1.0.0"
}
  • name:项目的包名,必须唯一(如果要发布到 NPM)。
  • version:项目版本号,通常遵循 语义化版本(SemVer)规则。

语义化版本格式是 主版本.次版本.修订号,比如 1.2.3

  • 主版本(Major):不兼容的 API 修改。
  • 次版本(Minor):向下兼容的功能新增。
  • 修订号(Patch):向下兼容的问题修复。

description 和 keywords

package.json
{
    "description": "一个学习 NPM 的示例项目",
    "keywords": ["npm", "tutorial", "frontend"]
}
  • description:项目描述,帮助别人快速了解项目。
  • keywords:关键词数组,发布到 NPM 后方便搜索。

main 和 type

package.json
{
    "main": "index.js",
    "type": "module"
}
  • main:指定包的入口文件,别人 require('你的包') 时会加载这个文件。
  • type:设为 module 表示项目默认使用 ES Modules,可以用 import/export 语法;不设置则默认使用 CommonJS。
type: "module" 只对 Node.js 项目有意义。前端项目通常由打包工具处理模块格式,不一定需要设置这个字段。

scripts

package.json
{
    "scripts": {
        "start": "node index.js",
        "dev": "node --watch index.js",
        "build": "webpack --mode=production"
    }
}

scripts 是命令脚本集合,执行时用 npm run 脚本名。比如:

npm run dev
npm run build
starttest 是两个特殊脚本,可以直接用 npm startnpm test 运行,不用加 run

dependencies 和 devDependencies

这是最重要的两个字段,但初学者经常混淆。

package.json
{
    "dependencies": {
        "vue": "^3.5.0"
    },
    "devDependencies": {
        "eslint": "^9.22.0"
    }
}
字段用途是否参与生产构建
dependencies项目运行时需要的包,比如 Vue、Axios、dayjs
devDependencies开发时需要的工具,比如 ESLint、Webpack、TypeScript
简单来说:用户访问你的网站时必须用到的包,放在 dependencies;只有写代码时才用到的工具,放在 devDependencies

安装时可以指定放到哪个字段:

npm install vue           # 默认加入 dependencies
npm install eslint -D     # -D 是 --save-dev 的简写,加入 devDependencies

🪤 如果我把开发依赖也放到 dependencies 会怎样

初学者常想:“反正都能安装,分那么清干嘛?” 实际上,放错字段会带来几个真实问题:

1. 生产环境会安装不必要的包

很多部署流程会执行:

npm install --production

这个命令只安装 dependencies,跳过 devDependencies。如果你把 eslintwebpacktypescript 都塞进 dependencies,它们也会被装到生产服务器上。

对于前端项目,Vue、React 等框架最终会被打包进产物,但 ESLint、Prettier、测试工具不会被打包。不过它们依然会占用服务器磁盘、拖慢安装速度,并增加安全风险。

2. 部署包变大

假设你的项目生产环境只需要 vueaxios,但你把 webpackeslintsass 也放进了 dependencies

package.json
{
    "dependencies": {
        "vue": "^3.5.0",
        "axios": "^1.7.9",
        "webpack": "^5.97.0",
        "eslint": "^9.22.0",
        "sass": "^1.89.2"
    }
}

部署时服务器会多下载几十个甚至上百个无关包,因为每个包还有自己的依赖树。最终镜像体积变大,上传和启动时间都变长。

3. 安全漏洞面扩大

生产环境每多一个包,就多一份潜在的安全隐患。eslintwebpack 这类工具依赖非常多,其中任意一个子包出现漏洞,都会影响你的生产环境安全评分。

4. 构建产物不会因此变大,但构建过程会变乱

现代前端打包工具(Webpack、Vite、Rollup)默认不会把 devDependencies 里的工具代码打进最终 bundle。所以即使你放错字段,用户访问的 JS/CSS 文件通常不会变大。

但你的 node_modules 会变臃肿,npm audit 扫出的漏洞会更多,排查问题时也更难理清真正需要的依赖。


💡 一个简单判断标准

装包前问自己:“这个包在服务器上运行时还需要吗?”

  • 需要 → dependencies(如 Vue、Axios、dayjs、Express)
  • 不需要 → devDependencies(如 ESLint、Prettier、Webpack、TypeScript、测试框架)
如果你写的是一个 Node.js 后端服务,dependencies 就是启动服务时真正用到的包;开发时用的调试工具、测试库都属于 devDependencies

engines

package.json
{
    "engines": {
        "node": ">=18.0.0",
        "npm": ">=9.0.0"
    }
}

engines 用于声明项目运行的 Node.js 和 NPM 版本要求。它只是一个提示,不会自动阻止安装,但可以配合 .npmrc 强制校验。


🛠 一个完整的 package.json 示例

package.json
{
    "name": "npm-study-demo",
    "version": "1.0.0",
    "description": "学习 NPM 用法的示例项目",
    "main": "index.js",
    "type": "module",
    "scripts": {
        "start": "node index.js",
        "dev": "node --watch index.js",
        "lint": "eslint ."
    },
    "keywords": ["npm", "study"],
    "author": "前端小白",
    "license": "MIT",
    "dependencies": {
        "dayjs": "^1.11.13"
    },
    "devDependencies": {
        "eslint": "^9.22.0"
    },
    "engines": {
        "node": ">=18.0.0"
    }
}

🧾 小节总结

  • package.json 是项目的核心配置文件,包含项目信息、依赖和脚本。
  • dependencies 放运行时依赖,devDependencies 放开发工具。
  • 开发工具错放到 dependencies 会导致生产环境包体积变大、安装变慢、安全风险增加。
  • 版本号遵循语义化规则:主版本.次版本.修订号
  • scripts 可以把长命令封装成 npm run xxx

❓ 知识问答

Q1:dependenciesdevDependencies 有什么区别?

A:dependencies 是项目运行必须的依赖,会随生产构建打包;devDependencies 只是开发工具,不会被打包到生产环境。

Q2:如果把 eslintwebpack 这些开发工具也放进 dependencies 会怎样?

A:会导致生产环境多安装不必要的包,部署包变大,安全漏洞面扩大,但通常不会影响最终前端打包产物的大小。

Q3:^1.2.3~1.2.3 有什么区别?

A:^ 允许更新到不改变最左边非零数字的版本,比如 ^1.2.3 允许 1.x.x 但不允许 2.0.0~ 只允许更新修订号,比如 ~1.2.3 只允许 1.2.x

Q4:npm install eslint -D 里的 -D 是什么意思?

A:-D--save-dev 的简写,表示把包安装到 devDependencies 中。

Q5:main 字段有什么用?

A:当别人引入你的包时,NPM 会根据 main 字段找到入口文件并加载。


🧪 小练习

请打开你上节课创建的 npm-demo 项目,完成以下修改:

  1. package.json 添加 descriptionkeywords
  2. 添加一个 scripts 命令 hello,执行 node -e "console.log('Hello NPM')"
  3. 安装 eslintdevDependencies
# 请在这里输入安装命令
  1. 检查 package.json,确认 eslint 出现在正确的字段中。

🎉 恭喜你掌握了 package.json 的核心字段!下一篇我们会学习各种安装命令和版本控制,让你的依赖管理更加得心应手。