貌似很多开发者干了很多年,对package.json都不够了解,现在通过这篇文章和大家一起来认识一下package.json中的相关知识。
一、package.json的核心作用
在了解具体字段前,我们先明确package.json
的本质:它是一个JSON格式的项目元数据文件,主要用于:
- 描述项目基本信息:名称、版本、作者、许可证等
- 声明依赖关系:项目运行和开发所需的第三方包
- 定义脚本命令 :通过
npm run
执行的脚本(如dev
、build
) - 配置工具行为:告诉打包工具、测试框架等如何处理项目
- 发布配置:当项目作为npm包发布时,控制发布内容和行为
简单说,package.json
是项目的"说明书",既是给开发者看的文档,也是给工具链读的配置文件。
二、标准字段:npm官方定义的核心属性
标准字段是npm规范中明确定义的属性,大部分具有跨工具的通用性。我们按重要性分为核心字段 、依赖管理字段 、脚本与配置字段 和发布相关字段四类。
1. 核心元信息字段(必填/关键)
这些字段描述项目的基本标识信息,其中name
和version
是发布npm包时的必填项。
字段名 | 类型 | 是否必填 | 描述 | 注意事项 |
---|---|---|---|---|
name |
字符串 | 是(发布时) | 项目名称,作为npm包发布时的唯一标识 | 不能包含大写字母、空格,建议用kebab-case(如my-project );长度≤214字符 |
version |
字符串 | 是(发布时) | 版本号,必须符合语义化版本(SemVer)规范 | 格式为MAJOR.MINOR.PATCH (如1.2.3 );发布后不能修改同版本内容 |
description |
字符串 | 否 | 项目描述,会显示在npm官网和npm info 命令结果中 |
简洁明了,便于他人理解项目用途 |
author |
字符串/对象 | 否 | 项目作者,格式可为"Name <email@example.com> (url)" 或对象形式 |
多人协作可用contributors 数组(格式相同) |
license |
字符串 | 否 | 开源许可证类型(如MIT 、Apache-2.0 ) |
避免使用licenses (旧格式);私有项目可省略或设为"UNLICENSED" |
private |
布尔值 | 否 | 标记项目是否为私有 | 设为true 时,npm会阻止意外发布(重要!内部项目必设) |
示例:
json
{
"name": "react-hooks-utils",
"version": "2.3.0",
"description": "A collection of useful React hooks",
"author": "John Doe <john@example.com> (https://johndoe.dev)",
"license": "MIT",
"private": false
}
2. 依赖管理字段(核心功能)
这些字段定义项目依赖的第三方包,是package.json
最常用的功能之一。
字段名 | 类型 | 描述 | 安装命令示例 |
---|---|---|---|
dependencies |
对象 | 项目运行时依赖(如React、Lodash),生产环境必需 | npm install react |
devDependencies |
对象 | 项目开发时依赖(如Webpack、ESLint),生产环境不需要 | npm install -D webpack |
peerDependencies |
对象 | 同伴依赖,声明项目需要的宿主环境版本(如UI组件库依赖特定React版本) | 无需手动安装,由宿主项目提供 |
peerDependenciesMeta |
对象 | 配置peer依赖的可选性(如{"react": {"optional": true}} ) |
配合peerDependencies 使用 |
optionalDependencies |
对象 | 可选依赖,安装失败不会导致整个安装过程失败 | npm install --save-optional fsevents |
bundledDependencies |
数组 | 发布时需要打包的依赖(极少用,通常用dependencies ) |
需手动列出包名数组 |
关键区别:
dependencies
vsdevDependencies
:前者会被npm install --production
安装,后者不会;打包工具(如Webpack)默认会将dependencies
的内容纳入产物。peerDependencies
的典型场景:UI组件库(如Ant Design)声明对React的版本要求,确保使用者的React版本兼容。
示例:
json
{
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@types/react": "^18.0.0",
"vite": "^4.0.0"
},
"peerDependencies": {
"react": ">=17.0.0"
},
"peerDependenciesMeta": {
"react": { "optional": false }
}
}
3. 脚本与配置字段
这些字段控制项目的脚本命令和工具链行为。
字段名 | 类型 | 描述 | 示例 |
---|---|---|---|
scripts |
对象 | 定义可通过npm run <key> 执行的脚本命令 |
{"dev": "vite", "build": "vite build"} |
config |
对象 | 定义脚本中可访问的配置变量(通过npm_config_<key> 访问) |
{"port": 3000} → 脚本中可通过$npm_config_port 获取 |
engines |
对象 | 声明项目运行所需的Node.js或npm版本范围 | {"node": ">=16.0.0", "npm": ">=8.0.0"} |
engineStrict |
布尔值 | 强制检查engines 声明(npm 3.x后已废弃,改用.npmrc 的engine-strict=true ) |
- |
scripts
字段进阶:
- 内置钩子:如
prebuild
(build
前执行)、postbuild
(build
后执行),无需显式调用 - 环境变量:可访问
NODE_ENV
等环境变量,或通过cross-env
跨平台设置自定义变量 - 简写命令:
npm start
等价于npm run start
,npm test
等价于npm run test
示例:
json
{
"scripts": {
"dev": "vite",
"prebuild": "eslint .",
"build": "vite build",
"postbuild": "echo Build completed!",
"test": "vitest run"
},
"config": {
"apiUrl": "https://api.example.com"
},
"engines": {
"node": ">=18.0.0"
}
}
4. 发布与文件控制字段
这些字段控制npm包的发布行为和文件包含/排除规则。
字段名 | 类型 | 描述 | 注意事项 |
---|---|---|---|
main |
字符串 | 包的入口文件路径,require('包名') 时会加载该文件 |
默认为index.js ;ESM项目可用module 字段(非标准,但被广泛支持) |
module |
字符串 | ESM模块入口(非标准,被Rollup、Webpack等工具支持) | 用于区分CommonJS和ESM入口 |
browser |
字符串/对象 | 浏览器环境的入口文件,用于替代main (适用于同时支持Node和浏览器的包) |
可指定{"main": "./browser.js"} ,工具会优先使用浏览器版本 |
files |
数组 | 发布时需要包含的文件/目录列表(白名单) | 支持通配符(如"dist/*" );与.npmignore 文件作用相反(黑名单) |
bin |
字符串/对象 | 定义可执行命令,发布后会被链接到npm的全局bin目录 | 如{"my-cli": "./bin/cli.js"} ,安装后可直接运行my-cli 命令 |
types /typings |
字符串 | TypeScript类型定义文件路径 | 默认为index.d.ts ,用于提供类型提示 |
repository |
字符串/对象 | 代码仓库地址,会显示在npm官网 | 格式如"github:username/repo" 或{"type": "git", "url": "..."} |
homepage |
字符串 | 项目主页URL(如文档地址) | - |
bugs |
字符串/对象 | 问题反馈地址(如GitHub Issues) | 如{"url": "https://github.com/xxx/issues"} |
示例:
json
{
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"browser": "dist/browser.js",
"files": ["dist", "README.md", "LICENSE"],
"bin": {
"calc": "./bin/calc.js"
},
"types": "dist/index.d.ts",
"repository": "github:my-org/calculator",
"homepage": "https://my-org.github.io/calculator/",
"bugs": {
"url": "https://github.com/my-org/calculator/issues"
}
}
三、非标准字段:工具链与生态扩展
非标准字段(也称"自定义字段")并非npm规范定义,但被各类工具、框架广泛采用,用于配置特定功能。它们通常有两种形式:
- 工具特定字段 :如
eslintConfig
、jest
,由对应工具直接读取 - 命名空间字段 :以特定前缀开头(如
vue
、next
),用于框架配置 - 完全自定义字段 :通常以
_
开头(如_myProjectConfig
),避免冲突
1. 构建工具相关字段
字段名 | 关联工具 | 描述 |
---|---|---|
browserlist |
autoprefixer、Babel | 定义目标浏览器范围(如["last 2 versions", "not dead"] ) |
babel |
Babel | Babel配置(替代.babelrc 文件) |
webpack |
Webpack | Webpack配置(通常用于简单配置,复杂配置仍用单独文件) |
vite |
Vite | Vite配置选项(如{"resolve": {"alias": {"@": "./src"}}} ) |
rollup |
Rollup | Rollup打包配置 |
2. 代码质量与测试工具字段
字段名 | 关联工具 | 描述 |
---|---|---|
eslintConfig |
ESLint | ESLint配置(规则、解析器等) |
prettier |
Prettier | Prettier格式化配置(如{"singleQuote": true} ) |
jest |
Jest | Jest测试框架配置 |
vitest |
Vitest | Vitest测试框架配置 |
lint-staged |
lint-staged | 定义Git暂存区文件的lint规则(如{"*.js": ["eslint --fix"]} ) |
3. 框架与库特定字段
字段名 | 关联框架/库 | 描述 |
---|---|---|
vue |
Vue.js | Vue CLI项目配置(如{"version": 3, "css": {"extract": false}} ) |
next |
Next.js | Next.js配置(如{"reactStrictMode": true} ) |
nuxt |
Nuxt.js | Nuxt.js配置(如{"srcDir": "src/", "generate": {"dir": "dist"}} ) |
react |
React | 极少用,某些工具用于指定React版本兼容信息 |
workspaces |
npm/yarn/pnpm | Monorepo工作区配置(如["packages/*"] ) |
4. 其他常用非标字段
字段名 | 用途 |
---|---|
funding |
项目资助信息(如{"type": "github", "url": "https://github.com/sponsors/xxx"} ) |
keywords |
项目关键词数组(如["react", "hooks", "utils"] ),用于npm搜索 |
publishConfig |
发布配置(如{"registry": "https://custom-registry.com"} ),覆盖默认发布行为 |
sideEffects |
告知Webpack等工具哪些文件有副作用(不能被Tree-Shaking移除),如["*.css"] |
非标字段示例:
json
{
"browserlist": ["last 2 versions", "not ie <= 11"],
"eslintConfig": {
"extends": ["eslint:recommended", "plugin:react/recommended"],
"parserOptions": { "ecmaVersion": 2020 }
},
"prettier": {
"singleQuote": true,
"trailingComma": "es5"
},
"vite": {
"server": { "port": 3000 },
"build": { "target": "es2015" }
},
"workspaces": ["packages/*"],
"keywords": ["vite", "react", "template"],
"publishConfig": {
"access": "public"
}
}
四、注意事项
-
必选字段检查:
- 发布到npm的包必须包含
name
和version
- 内部项目建议设置
"private": true
,防止意外发布 - 至少添加
description
和keywords
,提升包的可发现性
- 发布到npm的包必须包含
-
依赖管理原则:
- 区分
dependencies
和devDependencies
,避免生产环境包含冗余依赖 - 谨慎使用
peerDependencies
,明确声明版本范围(避免过宽或过窄) - 不要将
node_modules
目录提交到Git,通过package-lock.json
锁定版本
- 区分
-
非标字段规范:
- 自定义字段建议添加项目前缀(如
myAppConfig
),避免与工具字段冲突 - 复杂配置优先使用单独文件(如
.eslintrc.js
),而非塞进package.json
- 了解工具对字段的支持情况(如
module
字段并非所有工具都兼容)
- 自定义字段建议添加项目前缀(如
-
版本号管理:
- 严格遵循语义化版本(SemVer),避免随意升级主版本
- 使用
~
和^
控制版本范围(如~1.2.3
允许补丁更新,^1.2.3
允许次版本更新)
五、总结
package.json
是项目的"神经中枢",既包含描述项目的元数据,也承载着工具链的配置规则。理解标准字段能帮助你正确管理依赖和发布流程,而掌握非标字段则能让你更高效地使用各类开发工具。
随着前端生态的发展,package.json
的功能还在不断扩展,但核心始终是"描述项目、连接工具"。合理配置每个字段,不仅能提升项目的可维护性,也是前端工程化能力的重要体现。
最后,推荐两个实用工具帮助你管理package.json
:
- npm-package-json-lint:检查
package.json
的规范性 - syncpack:在Monorepo中同步依赖版本
希望本文能帮你彻底搞懂package.json
,让你的项目配置更加规范高效!