前言
每一个 Node.js 项目都绕不开一个文件------package.json。
它像项目的"身份证",又像"瑞士军刀":
- 告诉 npm 你是谁(name、version、license)
- 告诉打包器 怎么引入你(main、module、exports)
- 告诉 CI 怎么测试你(scripts.test)
- 告诉用户 怎么使用你(bin、scripts、dependencies)
本文用"渐进式"结构,带你从最小可运行 一路到企业级开源库所需的全部字段与技巧。读完可以:
- 手写零报错
package.json - 正确拆分
dependencies与peerDependencies - 让 webpack/vite/Node 同时识别你的库
- 避免 90% 的"为什么本地能跑,一发包就崩"
1. 最小可运行版本(MVP)
新建文件夹,执行 npm init -y,得到:
json
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
即可:
node index.js运行npm test触发脚本
但离"能用"还差 3 件事:
- 把
license换成 SPDX 标准标识(MIT/Apache-2.0) - 加
"private": true,防止误发 npm - 删除无用字段,保留核心 6 项:
json
{
"name": "demo",
"version": "1.0.0",
"main": "index.js",
"private": true,
"scripts": {
"start": "node index.js"
},
"license": "MIT"
}
2. 依赖管理三板斧
| 场景 | 命令 | 写入字段 | 例子 |
|---|---|---|---|
| 生产依赖 | npm i lodash |
dependencies |
"lodash": "^4.17.21" |
| 开发依赖 | npm i -D vite |
devDependencies |
"vite": "^5.0.0" |
| 宿主依赖 | 手动写 | peerDependencies |
"react": ">=18.0.0" |
口诀:
下游需要运行 →
dependencies只是构建/测试 →
devDependencies防止多实例 →
peerDependencies
踩坑:
peerDependencies版本范围过严会导致用户无法安装!
✅ 正确:">=16.8.0"
❌ 错误:"16.8.0"(只允许 exact 版本)
3. 脚本进阶:一条命令跑完开发全流程
json
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"test": "vitest",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"prepare": "husky install",
"prepublishOnly": "npm run build && npm test"
}
生命周期图解:
arduino
npm install → 触发 prepare → 自动装 husky 钩子
npm publish → 触发 prepublishOnly → 保证发布的是 dist 产物
跨平台兼容:
json
"build": "cross-env NODE_ENV=production tsc && vite build"
4. 让三方库正确引入你:main vs module vs exports
| 字段 | 历史地位 | 适用场景 | 备注 |
|---|---|---|---|
main |
CommonJS 时代 | 老项目兼容 | 仅支持单一路径 |
module |
社区约定 | ESM 打包工具 | 无官方标准 |
exports |
Node 12+ 官方 | 统一替代上面两项 | 支持条件导出、子路径 |
现代库模板:
json
{
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./utils": {
"types": "./dist/utils.d.ts",
"import": "./dist/utils.mjs",
"require": "./dist/utils.cjs"
}
}
}
收益:
import {} from 'your-lib/utils'直接子路径- 用户 CommonJS / ESM 均可使用
- TypeScript 提示不丢失
5. 发布配置:让包体积瘦身 70%
json
{
"files": ["dist", "README.md", "LICENSE"],
"sideEffects": false,
"publishConfig": {
"registry": "https://registry.npmjs.org",
"access": "public"
}
}
files白名单:防止把源码、测试、脚本发到 npmsideEffects: false告诉 webpack 可以摇树优化- 公司内网发布:
registry指向私有 Verdaccio / Nexus
6. 企业级开源库 checklist
| 步骤 | 工具 / 字段 | 命令 |
|---|---|---|
| 1. 版本号合规 | SemVer | npm version patch |
| 2. 依赖漏洞扫描 | npm audit | npm audit fix |
| 3. 声明 Node 版本 | engines | { "node": ">=18.0.0" } |
| 4. 协议合规 | license | npx license-checker |
| 5. 自动化发布 | GitHub Actions | npm publish 在 CI 触发 |
示例 CI 片段(.github/workflows/publish.yml):
yaml
- name: Publish
if: github.ref == 'refs/heads/main'
run: |
npm config set //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}
npm publish
7. 可视化总结:一张思维导图
(文字版)
java
package.json
├─ 元信息(name、version、license、private)
├─ 依赖(dependencies / dev / peer / optional)
├─ 脚本(scripts + 生命周期)
├─ 入口(main → module → exports 渐进)
├─ 发布(files、sideEffects、publishConfig)
└─ 约束(engines、os、cpu)
8. 常见报错速查表
| 报错 | 原因 | 快速修复 |
|---|---|---|
Cannot find module 'xxx' |
忘了把 dist 加入 files |
补 files:["dist"] |
Multiple versions of React |
把 react 放 dependencies |
改 peerDependencies |
npm WARN deprecated xxx |
依赖版本过老 | npx npm-check-updates -u |
403 Forbidden on publish |
包名冲突或未登录 | 换名 / npm login |
9. 结语
package.json 很小,却贯穿了 Node.js 项目的全生命周期:
开发 → 测试 → 构建 → 发布 → 依赖治理。
掌握它,你就拥有了:
- 更小的包体积
- 更快的安装速度
- 更少的"在我电脑能跑"事故
把本文 checklist 保存为备忘录,下次新建项目直接套用,即可一步到位。
Happy coding!
10. 附录:模板仓库
GitHub 搜 npm-lib-boilerplate-2025,已集成:
- TypeScript + Vite + Vitest
- GitHub Actions 自动发布
- husky + lint-staged 代码检查
- 示例
package.json与本文明细 100% 对应
克隆即可开始你的下一个开源库。