"name"string包名称。必须小写且 URL 安全,不能有空格,连字符和下划线可以。作用域包用 @scope/name 格式。用户 `npm install <name>` 时就用这个名字。
"name": "my-lib""name": "@myorg/utils"package.json 字段速查,55+ 字段配真实示例,双语可搜索。
54 个字段
"name"string包名称。必须小写且 URL 安全,不能有空格,连字符和下划线可以。作用域包用 @scope/name 格式。用户 `npm install <name>` 时就用这个名字。
"name": "my-lib""name": "@myorg/utils""version"string语义化版本,格式 MAJOR.MINOR.PATCH。发布时必填。递增规则:MAJOR 破坏性变更,MINOR 新功能,PATCH 修复。预发布版: 1.0.0-alpha.1。
"version": "1.0.0""version": "2.4.1""version": "0.0.1-alpha.1""description"string显示在 npm 搜索结果的一句话描述。保持简洁准确,不要写营销语。在 registry 页面和 `npm search` 输出里都会显示。
"description": "Fast CSV parser for Node.js""keywords"string[]提高 npm 搜索可发现性的关键词数组。想想用户在需要你提供的功能时会搜什么词。
"keywords": ["csv", "parser", "streaming", "tsv"]"homepage"string项目官网或文档页面的 URL。在 npm registry 页面上显示为链接。
"homepage": "https://github.com/myorg/my-lib#readme""bugs"string | { url?: string; email?: string }Bug 报告的 issue tracker URL 和/或邮箱。npm 将此作为"报告漏洞"链接。可以是 URL 字符串,也可以是包含 url 和 email 的对象。
"bugs": "https://github.com/myorg/my-lib/issues""bugs": { "url": "https://github.com/myorg/my-lib/issues", "email": "bugs@example.com" }"license"stringSPDX 许可证标识符。填 "MIT"、"ISC"、"Apache-2.0"、"GPL-3.0" 等。私有/商业包写 "UNLICENSED" 表明不开源。
不写 license 默认法律含义是"保留所有权利"。闭源包明确写 "UNLICENSED" 避免歧义。
"license": "MIT""license": "Apache-2.0""license": "UNLICENSED""author"string | { name: string; email?: string; url?: string }包作者。可以是 "Name <email> (url)" 简写字符串,也可以是包含 name、email、url 字段的对象。
"author": "Tanya Ivanova <t@example.com> (https://example.com)""author": { "name": "Tanya Ivanova", "email": "t@example.com" }"contributors"Array<string | { name: string; email?: string }>贡献者列表,格式与 author 相同。可选字段 — git log 才是贡献记录的权威来源。
"contributors": ["Alice <a@example.com>", "Bob <b@example.com>"]"repository"string | { type: string; url: string; directory?: string }源代码仓库地址。npm 在包页面显示"Repository"链接,也让 `npm repo` 能直接打开浏览器。monorepo 包加 directory 字段。
"repository": { "type": "git", "url": "https://github.com/myorg/my-lib.git" }"repository": "github:myorg/my-lib""repository": { "type": "git", "url": "https://github.com/myorg/mono.git", "directory": "packages/my-lib" }"funding"string | { type: string; url: string } | Array资助渠道。npm 安装时显示 funding 提示,`npm fund` 命令会列出项目中所有填了此字段的包。
"funding": "https://github.com/sponsors/myorg""funding": { "type": "opencollective", "url": "https://opencollective.com/babel" }"funding": [{ "type": "github", "url": "https://github.com/sponsors/myorg" }, { "type": "patreon", "url": "https://www.patreon.com/myorg" }]"scripts"Record<string, string>通过 `npm run <key>` 执行的 Shell 命令。start、test、stop、restart 可以省略 run 直接跑。所有脚本执行时 node_modules/.bin 都自动加进 PATH。
"scripts": { "build": "tsc", "test": "vitest run", "lint": "eslint src" }"scripts": { "start": "node dist/index.js", "dev": "tsx watch src/index.ts" }"scripts.prepare"string在打包或发布前自动运行,也在本地 `npm install` 时(包括从 git 安装)触发。常用于发布前构建。
本地 `npm install` 也会触发,可能拖慢开发时安装速度。如果只想在发布时构建,改用 prepublishOnly。
"prepare": "npm run build""prepare": "husky install""scripts.prepublishOnly"string只在 `npm publish` 前运行,install 时不触发。比 prepare 更安全,适合只在发布前做的检查(如先跑测试再发布)。
"prepublishOnly": "npm test && npm run build""scripts.postinstall"string包安装完后自动运行。原生扩展包常用来编译 C++ 绑定。注意:任何包的 postinstall 都会自动执行,要审查你安装的包。
CI 里用 `npm install --ignore-scripts` 跳过所有生命周期脚本更安全。之后只手动运行你明确信任的脚本。
"postinstall": "node-gyp rebuild""postinstall": "node ./scripts/setup.js""scripts.pre<name> / post<name>"string自动在 `npm run <name>` 前后执行的生命周期钩子。可用于任意自定义脚本名。如 prebuild 在 build 之前自动跑。
"prebuild": "rm -rf dist""postbuild": "node ./scripts/post-build.js""pretest": "eslint src""config"Record<string, string>在 npm 脚本中通过 `npm_package_config_<key>` 环境变量访问的默认配置值。用户可以用 `npm config set <包名>:<key> <值>` 覆盖,无需修改 package.json。
"config": { "port": "3000" }// in scripts: "start": "node server.js" // $npm_package_config_port is "3000""dependencies"Record<string, string>运行时依赖包。别人从 npm 安装你的包时自动安装这些。semver 范围:`^` 允许同主版本兼容更新,`~` 只允许 patch 更新。
"dependencies": { "express": "^4.18.0", "lodash": "~4.17.21" }"dependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" }"devDependencies"Record<string, string>只在开发阶段需要的包(打包器、测试框架、Linter、类型检查器)。别人从 npm 安装你的包时不会安装这些。
库输出的 TypeScript 类型声明的依赖包放 devDependencies 就行。typescript 包本身也放这里,不要放 dependencies。
"devDependencies": { "typescript": "^5.0.0", "vitest": "^1.0.0", "eslint": "^9.0.0" }"peerDependencies"Record<string, string>需要使用方自行安装的依赖。用于插件、框架适配器和必须与宿主共享实例的库(如 react、webpack)。
peerDependencies 不会自动安装。npm 7+ 会警告但不一定安装。用户漏装会在运行时报不明不白的错,而不是在 install 时报错。
"peerDependencies": { "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }"peerDependencies": { "webpack": ">=4.0.0" }"peerDependenciesMeta"Record<string, { optional?: boolean }>每个 peerDependency 的元数据。设 `{ "optional": true }` 后,缺少该 peer 时不再显示警告。
"peerDependenciesMeta": { "typescript": { "optional": true }, "sass": { "optional": true } }"optionalDependencies"Record<string, string>npm 尝试安装但失败了也不报错的依赖(如原生扩展提供的可选功能)。你的代码必须处理它们不存在的情况。
"optionalDependencies": { "fsevents": "^2.3.0" }// in code: let fsevents; try { fsevents = require("fsevents"); } catch {}"bundleDependencies"string[] | boolean发布时打进 tarball 里的依赖名称列表。适合不能依赖 npm 可用性的离线部署或供应商锁定包。
打包依赖会大幅增加 tarball 体积。只在有明确理由时使用:离线部署、私有 fork、必须自包含的包。
"bundleDependencies": ["my-vendored-lib", "internal-tool"]"overrides" (npm ≥8.3)Record<string, string | object>强制所有传递依赖中某个包使用指定版本。常用于在上游维护者发布修复前自行应用安全补丁。
"overrides": { "minimist": "^1.2.6" }"overrides": { "react": "^18.0.0", "some-pkg": { "lodash": "4.17.21" } }"resolutions" (Yarn)Record<string, string>npm overrides 的 Yarn 等价字段。强制传递依赖使用特定版本。Yarn Classic 和 Berry 的 glob 语法有细微差异。
"resolutions": { "minimist": "^1.2.6", "**/lodash": "4.17.21" }"files"string[]`npm publish` 时包含的文件/目录白名单。未列出的文件被排除。不填则包含所有文件(忽略 .gitignore)。推荐用 files 而不是 .npmignore。
package.json、README、LICENSE 和 main 入口文件无论如何都会被包含,无法通过 files 排除。
"files": ["dist", "src", "!src/**/*.test.ts"]"files": ["lib", "types", "README.md"]"private"boolean防止意外发布。设为 true 时 npm 会拒绝任何 `npm publish` 命令。应用仓库和 monorepo 根目录必须设置。
"private": true"publishConfig"object只在 `npm publish` 时生效的配置覆盖。常见用途:指向私有 registry、设置 dist-tag、修改 scoped 包的访问权限。
"publishConfig": { "access": "public" }"publishConfig": { "registry": "https://npm.mycompany.com", "tag": "next" }"main"string旧版 CJS 入口文件。`require("your-package")` 时返回该文件。仍被旧工具和 Node < 12 使用。定义了 exports 后,Node 12+ 优先使用 exports 而忽略 main。
一旦定义 exports,Node 12+ 就不再读 main。main 只留作极老工具的兜底。
"main": "./dist/index.js""main": "lib/index.js""module"string非官方但被打包器(Rollup、Webpack、Vite)广泛支持的 ESM 入口。打包器优先使用它来启用 Tree-shaking。Node.js 本身不读这个字段。
"module": "./dist/index.esm.js""module": "esm/index.js""browser"string | Record<string, string | false>浏览器环境下替代 main 的入口。打包浏览器版本时,打包器用这个文件替换 main。对象形式可以对特定文件重映射,或设 false 完全排除。
"browser": "./dist/index.browser.js""browser": { "./lib/node-fs.js": "./lib/browser-fs.js", "./lib/net.js": false }"exports"string | object显式包入口映射。精确定义哪些子路径可以被导入。未声明的路径直接抛 ERR_PACKAGE_PATH_NOT_EXPORTED,让内部实现真正私有。
给已有包新增 exports 是破坏性变更 — 用户直接导入的子路径(如 `yourpkg/lib/utils`)会失效。应该升主版本号。
"exports": "./dist/index.js""exports": { ".": { "import": "./dist/index.mjs", "require": "./dist/index.cjs" }, "./utils": "./dist/utils.js" }"exports" — conditional keysobject (within exports entry)exports 路径内的条件键:import 对应 ESM import,require 对应 CJS require(),browser 给打包器,types 给 TypeScript,default 是兜底条件。
"exports": { ".": { "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js", "types": "./dist/index.d.ts", "default": "./dist/cjs/index.js" } }"imports"Record<string, string | object>包内自引用映射。让包内文件用 `import "#utils"` 代替深层相对路径如 `../../utils`。键名必须以 # 开头。Node 12.7+ 支持。
"imports": { "#utils": "./src/utils.js", "#db": { "node": "./src/db.node.js", "default": "./src/db.web.js" } }"bin"string | Record<string, string>安装时被软链到 node_modules/.bin 的 CLI 可执行文件(全局安装时进 PATH)。目标文件顶部需要 `#!/usr/bin/env node`。
"bin": "./cli.js""bin": { "my-tool": "./bin/my-tool.js", "my-tool-alt": "./bin/alt.js" }"type""module" | "commonjs".js 文件的解析方式。"module" → ES Module (import/export)。"commonjs"(默认)→ CommonJS (require)。用 .mjs/.cjs 扩展名覆盖单个文件的行为。
"type": "module""type": "commonjs""sideEffects"boolean | string[]`false` 告诉打包器所有文件都是纯函数 — 没用到的导出可以被删除(Tree-shaking)。数组形式列出确实有副作用的文件白名单。
`import "./styles.css"` 是副作用写法。全局设 `sideEffects: false` 会删掉 CSS。改用 `"sideEffects": ["*.css", "*.scss"]` 保留样式文件。
"sideEffects": false"sideEffects": ["*.css", "./src/polyfills.js"]"types" / "typings"string指向包根 TypeScript 声明文件 (.d.ts) 的路径。TypeScript 优先从这里查找类型。子路径的类型声明用 exports 里的 types 条件键。
"types": "./dist/index.d.ts""typings": "types/index.d.ts""workspaces"string[]指向 monorepo 中各本地包的 glob 模式。npm/Yarn/pnpm 会自动将它们软链到 node_modules,让包名可以直接 import。根 package.json 必须设置 "private": true。
"workspaces": ["packages/*"]"workspaces": ["apps/*", "packages/*", "!packages/internal"]"workspaces.nohoist" (Yarn)string[]Yarn 专有:阻止指定包被提升到根 node_modules。适用于必须和 workspace 放在一起的包(如 React Native)。
"workspaces": { "packages": ["packages/*"], "nohoist": ["**/react-native", "**/react-native/**"] }"engines"Record<string, string>声明需要的 Node.js(以及 npm/pnpm/yarn)版本范围。默认版本不匹配只警告不报错。在 .npmrc 里设 `engine-strict=true` 可让版本不匹配变成报错。
"engines": { "node": ">=18.0.0" }"engines": { "node": ">=16.0.0 <22", "npm": ">=8.0.0" }"os"string[]限制包可以安装在哪些操作系统上。值对应 process.platform:"linux"、"darwin"(macOS)、"win32"。前缀 ! 表示排除。
"os": ["linux", "darwin"]"os": ["!win32"]"cpu"string[]限制支持的 CPU 架构。值对应 process.arch:"x64"、"arm64"、"ia32"。原生扩展分发预构建二进制包时常用。
"cpu": ["x64", "arm64"]"cpu": ["!ia32"]"packageManager"string指定项目期望的包管理器及精确版本。Corepack 会强制执行 — 在项目里用错误的包管理器会直接报错。格式:name@semver。
"packageManager": "pnpm@8.15.0""packageManager": "yarn@4.1.0"Star range (*) in peerDependenciespeerDependencies 里写 `"react": "*"` 表示接受任意版本,包括不兼容的主版本。你的库会静默安装在 React 1 或 React 19 旁边。必须指定版本范围。
支持两个主版本用 `"^17.0.0 || ^18.0.0"` 写法。`||` 联合模式是声明多主版本 peer 支持的正确写法。
// bad: "peerDependencies": { "react": "*" }// good: "peerDependencies": { "react": "^17.0.0 || ^18.0.0" }"exports" blocks all unlisted sub-paths一旦设了 exports,所有未列出的路径都抛 ERR_PACKAGE_PATH_NOT_EXPORTED。给已有包新增 exports 字段是破坏性变更,即使只加了根路径 "."。
// before exports: import { helper } from "pkg/lib/helper" // worked// after exports (without listing ./lib/helper): same import THROWS"sideEffects: false" silently removes CSS如果包里有 `import "./globals.css"`,设 `"sideEffects": false` 会让 Webpack/Vite 把它 Tree-shake 掉。CSS 根本不会被加载。
// fix: "sideEffects": ["*.css", "*.scss", "./src/polyfills.js"]Forgetting "private": true in app repos没有 `"private": true`,在应用仓库里手滑跑 `npm publish` 会把整个应用公开发布,包括凭证和配置文件。
"private": true // must-have in all app repos and monorepo root package.json"files" wins over .npmignorefiles 和 .npmignore 同时存在时,.npmignore 完全失效。两者都没有时,npm 回退到 .gitignore。推荐只用 files:清晰且受版本控制。
"files": ["dist", "types"] // explicit allowlist beats any blacklistpeerDependencies are not auto-installednpm 7+ 对缺失的 peer 只警告,不一定安装。npm 3-6 完全不安装。用户必须在安装你的包的同时手动安装这些 peer。在 README 里写清楚。
README 里提供完整安装命令:`npm install your-lib react react-dom`。
"peerDependencies": { "react": "^18.0.0" }// consumer runs: npm install your-lib react"overrides" (npm) vs "resolutions" (Yarn)npm 用 overrides (v8.3+),Yarn 用 resolutions,两者不能互换。pnpm 和 npm 一样用 overrides。Yarn Classic 和 Berry 的 resolution glob 语法也不同。
// npm / pnpm: "overrides": { "lodash": "4.17.21" }// yarn classic: "resolutions": { "**/lodash": "4.17.21" }Lock file must be committed必须提交 package-lock.json / yarn.lock / pnpm-lock.yaml。没有 lock 文件,`npm install` 可能装到与测试时不同的(可能破坏性的)版本。
# .gitignore: DO NOT add package-lock.json or yarn.lock or pnpm-lock.yaml"engines" is advisory by defaultengines 字段默认只是建议:版本不匹配时 npm 只警告,仍然继续安装。要变成硬错误,在 .npmrc 里加 `engine-strict=true` 或传 --engine-strict 参数。
# .npmrc: engine-strict=true"engines": { "node": ">=18.0.0" }React in "dependencies" of a component libraryReact 组件库的 dependencies 里放 react,用户会装出两份 react(你的一份+他们自己的一份),导致 hooks(useContext、useState)失效并报不明所以的错。
所有必须是单例的包(react、react-dom、vue、webpack、styled-components)都放 peerDependencies,不要放 dependencies。
// bad: "dependencies": { "react": "^18" } in a component library// good: "peerDependencies": { "react": "^18" }涵盖日常 Node.js 和前端开发会遇到的所有 package.json 字段,共 55+ 项,按八大类整理:基本信息(name、version、description、keywords、 license、author、contributors、homepage、bugs、repository、funding)、 脚本(scripts 生命周期钩子、pre/post 钩子、config)、依赖管理 (dependencies、devDependencies、peerDependencies、 peerDependenciesMeta、optionalDependencies、bundleDependencies、 overrides、resolutions)、发布配置(files、private、publishConfig)、 模块解析(main、module、browser、exports、exports 条件、imports、bin、 type、sideEffects、types)、Workspaces(workspaces、nohoist)、运行 环境(engines、os、cpu、packageManager)、常见坑(peerDependencies 星号、exports 屏蔽内部路径、sideEffects:false 删 CSS、private:true 安全阀、files 与 .npmignore 的优先级、peer 不自动安装、overrides vs resolutions、lock 文件必须提交、engines 默认只是建议、依赖 vs peer 对框架库的区别)。每条显示 JSON 键名、值类型、字段用途及填写时机 说明,配 1–3 个可直接拷贝的示例。搜索框跨字段名、说明、示例过滤; 分类胶囊快速缩小范围;一键复制每个示例。全部在浏览器里跑,不上传。
把内容粘贴或拖入工具面板。
点击按钮,在浏览器内本地处理,文件不上传。
一键复制结果或下载到本地。
适合穿插在写代码、查问题、做 Review、上线前的小任务里。
这些入口会把当前任务接到更完整的工具链里。
npm 7+ 安装时对每个缺失的 peer 都会警告。你打开速查表查 peerDependenciesMeta, 给你的插件支持但不强制要求的 peer 加上 `{ "optional": true }`。 噪音警告消失了,真正需要这个 peer 的使用方也不受影响。
项目要拆成 packages/ 和 apps/ 两个目录。你查速查表确认 workspaces 的 glob 写法,确认根 package.json 需要加 "private": true,再加上 "packageManager" 锁定 pnpm 版本。十分钟后 workspace 软链建好了, `pnpm -r build` 顺利跑通所有包。
你要发布一个工具库,但不知道 tarball 里包含哪些文件以及如何暴露 API。速查表里依次看完 files(白名单)、exports(子路径控制)、 sideEffects: false(启用 Tree-shaking)和 publishConfig.access: public (scoped 包需要)。四个字段一次性填对。
React 组件库的 dependencies 里放 react — 用户会装出两份 react,导致 hooks 失效。应放 peerDependencies。
有 CSS/polyfill 副作用导入时设 sideEffects: false — 打包器会悄悄删掉这些文件。改用 "sideEffects": ["*.css"] 保留例外。
应用仓库忘记加 "private": true — 手滑跑一次 npm publish 整个项目就公开了。
全部在你的浏览器里跑。字段列表是内存里的静态数组,搜索框、分类胶囊、 复制按钮都不发任何网络请求。你输入的内容不会被记录也不会被上传。
做你这行的人, 还会一起用这些。