package.json、pnpm-lock.yaml 和 scripts 到底是什么
这是“从零读懂 Kita”系列的第二篇。上一篇先画仓库地图;这一篇阅读 Node 项目最重要的入口文件之一。
package.json 不是依赖清单而已
我最初看到 package.json,只会在 dependencies 中找框架版本。
实际上它同时回答:
1 | 项目叫什么 |
Kita 的开头是:
1 | { |
name、version 和 private
1 | "name": "kita", |
name 和 version 描述项目身份。private: true 阻止把这个应用误发布到 npm registry。
Kita 是应用仓库,不是准备给其他项目安装的 npm library,因此 private 是一条有用的防误操作边界。
type: module 是什么
1 | "type": "module" |
它表示项目默认使用 ECMAScript Modules,也就是常见的:
1 | import something from "some-package"; |
而不是旧式 CommonJS 的:
1 | const something = require("some-package"); |
这会影响 .js 文件怎样解释,也会影响配置和辅助脚本。它不是单纯的代码风格开关。
packageManager 为什么要固定版本
1 | "packageManager": "pnpm@10.28.2" |
这个字段告诉 Corepack 和协作者:项目不是泛泛地“使用 pnpm”,而是以哪个版本作为基线。
Dev Container 创建时执行 Corepack,再运行:
1 | pnpm install --frozen-lockfile |
这样新电脑不会因为使用另一个 pnpm 主版本而得到不同 lockfile 行为。
scripts 是项目的公共命令入口
Kita 的 scripts 分成几组。
开发与服务
1 | "dev": "... && pnpm dev:services && next dev", |
外部使用者只需要记住:
1 | pnpm dev |
脚本内部负责用户检查、数据库启动和 Next.js。脚本的价值就是把已经确认的顺序写进仓库。
质量检查
1 | "format:check": "... prettier . --check", |
pnpm check 不是测试业务行为,而是组合格式、静态检查和类型检查。
测试与构建
1 | "test": "pnpm test:unit && pnpm test:backup", |
每个脚本都代表一种验证。build 不能替代 test,test 也不能证明生产镜像的 entrypoint 一定正常。
Payload 与 Migration
1 | "payload:types": "... payload generate:types --use-swc", |
这些脚本把较长的 CLI 调用变成项目统一入口,并确保先执行 workspace 用户守卫。
怎样查看全部 scripts
在项目目录执行:
1 | pnpm run |
运行某个脚本可以写:
1 | pnpm run typecheck |
pnpm 也允许省略 run:
1 | pnpm typecheck |
命令来自仓库,不要求把 Next、Payload、Vitest 或 ESLint 全局安装到宿主机。
dependencies 与 devDependencies
Kita 的运行依赖包括:
1 | next / react |
它们参与应用运行、构建或生产功能。
开发依赖包括:
1 | typescript |
简单理解:
1 | dependencies |
这个边界不是绝对由“浏览器是否直接使用”决定。某些构建工具虽然不在最终 server 中运行,仍可能因为部署安装策略而需要谨慎放置。
版本符号 ^ 是什么
例如:
1 | "next": "^16.2.7" |
^ 表示允许在语义化版本规则下接受兼容范围内的更新。真正安装的完整版本组合记录在 lockfile 中。
因此不能只看 package.json 判断某次构建安装了什么,还要一起看 pnpm-lock.yaml。
pnpm-lock.yaml 解决什么
package.json 说明允许的依赖范围,lockfile 记录解析后的具体依赖图,包括间接依赖与完整性信息。
1 | package.json |
它应该进入 Git。新环境使用 --frozen-lockfile 时,如果 package.json 与 lockfile 不一致,安装会失败,而不是自动生成另一套结果。
不要手工大段编辑 lockfile。依赖变化应通过 pnpm 命令产生,再审查 package 和 lockfile 的 diff。
全局安装与项目依赖的区别
不推荐在 Windows 全局安装:
1 | next |
否则终端执行的版本可能与项目依赖不同。
项目脚本会优先使用当前 node_modules 中的工具。Dev Container、packageManager 和 lockfile 合在一起,才能让编辑器、本地命令和 CI 接近同一套版本。
安装一个新包前先问什么
1 | 它解决什么真实问题? |
安装后至少检查:
1 | git diff -- package.json pnpm-lock.yaml |
常见误解
- 修改
package.json不等于依赖已经安装; - 删除
node_modules不会删除 package 声明,但会影响当前工作环境; - lockfile 不是缓存文件;
pnpm dev是脚本入口,不是 pnpm 内置的 Next.js 功能;- dependency 数量多不等于项目更完整;
- CI 能安装依赖依赖于 package 与 lockfile 一致。
下一篇继续解释项目根目录中其他看似零散的配置文件各自负责什么。















