package.json 结构
package.json 是项目的身份证与清单:名称、版本、入口、依赖、脚本。它是 npm 安装与运行的根依据。
{
"name": "my-api",
"version": "1.0.0",
"type": "module",
"main": "dist/index.js",
"scripts": { "start": "node .", "dev": "node --watch ." },
"dependencies": { "express": "^4.19.2" },
"devDependencies": { "vitest": "^1.6.0" }
}设为 "module" 后,.js 被视为 ESM;否则是 CommonJS。新项目建议 ESM。
语义化版本
版本号 MAJOR.MINOR.PATCH。npm 用符号控制升级范围:^ 允许兼容的 MINOR/PATCH,~ 只允许 PATCH,* 任意。
| 写法 | 可升级到 | 适用 |
|---|---|---|
^1.2.3 | 1.x.x 最新 | 常规依赖(向下兼容) |
~1.2.3 | 1.2.x 最新 | 谨慎、仅补丁 |
1.2.3 | 仅此版本 | 锁定(配合 lockfile) |
package-lock.json 锁定依赖树,保证 CI 与本地一致。务必提交到版本库。
依赖类型
dependencies 是运行必需;devDependencies 仅开发/构建/测试用;peerDependencies 由宿主提供(库常用)。
npm i express # 写入 dependencies
npm i -D vitest # 写入 devDependencies
npm i -P react # 写入 peerDependenciesscripts 与生命周期
scripts 把常用命令固化。pre/post 前缀钩子会在同名脚本前后自动执行(如 prestart)。
{
"scripts": {
"build": "tsc",
"prestart": "npm run build",
"start": "node dist/index.js",
"test": "vitest run"
}
}npx 与可执行
npx 临时下载并运行某个包的可执行文件,无需全局安装。bin 字段声明的命令会被安装到 node_modules/.bin。
npx create-vite@latest my-app # 一次性脚手架
npm i -g pino-pretty # 全局安装(谨慎)
npx pino-pretty < app.log # 用本地/临时 bin全局包难以锁定版本、易团队不一致。优先 npx 或项目内 npm run 调用本地 bin。
workspaces 单体仓库
workspaces 让一个仓库包含多个包,共享顶层 node_modules,适合库 + 应用同仓管理。
{
"name": "monorepo",
"private": true,
"workspaces": ["packages/*"]
}npm install # 一次性安装所有 workspace 依赖
npm run build -w @org/ui # 只构建 ui 包发布与私有源
用 npm publish 发布到 registry。企业内部可指向私有源(如 Verdaccio、Nexus)。
npm version patch # 自增版本号并提交
npm publish --access public
npm config set registry https://私服地址用 .npmignore 或 files 字段限制发布内容;.env 与 node_modules 绝不能进包。
常见陷阱与 FAQ
把运行必需的放进 dev 会导致生产 npm install --production 缺依赖而崩溃;把仅测试用的放进 dependencies 会膨胀生产镜像。
必须提交。它是可复现安装的关键,CI 应使用 npm ci 严格按 lockfile 安装。
声明"我的库需要宿主提供某个版本",例如 React 组件库声明 peer react。避免重复打包 React 多份。