ai-notebook

NPM package.json 配置完全指南

1. 概述

1.1 什么是 package.json

package.json 是 Node.js 项目的核心配置文件,它:

每个 Node.js 项目的根目录都应该包含一个 package.json 文件。

1.2 创建 package.json

有多种方式创建 package.json

# 交互式创建(回答一系列问题)
npm init

# 使用默认值快速创建
npm init -y

# 使用 yarn
yarn init
yarn init -y

# 使用 pnpm
pnpm init

使用 npm init -y 创建的默认内容:

{
  "name": "my-project",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

1.3 字段分类概览

分类 字段 说明
必需字段 name, version 包的唯一标识
描述性字段 description, keywords, author, license, etc. 包的元信息
入口点字段 main, module, browser, exports, imports, type 模块解析入口
文件字段 files, bin, man, directories 发布包含的文件
脚本字段 scripts npm 命令脚本
依赖字段 dependencies, devDependencies, etc. 依赖管理
环境字段 engines, os, cpu 运行环境要求
发布字段 private, publishConfig 发布控制
工作空间 workspaces Monorepo 配置

2. 必需字段

2.1 name

包名称,是包的唯一标识符。

命名规则:

作用域包(Scoped Packages):

{
  "name": "@org/my-package"
}

作用域包的优点:

// 普通包名
{ "name": "lodash" }

// 作用域包名
{ "name": "@types/node" }
{ "name": "@vue/cli" }
{ "name": "@company/internal-utils" }

2.2 version

版本号,必须遵循语义化版本规范(SemVer)。

格式: MAJOR.MINOR.PATCH

{
  "version": "1.2.3"
}

版本号含义:

部分 含义 递增时机
MAJOR 主版本号 不兼容的 API 修改
MINOR 次版本号 向后兼容的功能性新增
PATCH 修订号 向后兼容的问题修正

预发布版本:

// alpha 版本(内部测试)
{ "version": "2.0.0-alpha.1" }

// beta 版本(公开测试)
{ "version": "2.0.0-beta.1" }

// rc 版本(候选发布)
{ "version": "2.0.0-rc.1" }

3. 描述性字段

3.1 description

简短描述包的功能,用于 npm 搜索结果展示。

{
  "description": "A lightweight utility library for date manipulation"
}

3.2 keywords

关键词数组,提高包在 npm 搜索中的可发现性。

{
  "keywords": ["date", "time", "utility", "format", "parse"]
}

3.3 homepage

项目主页 URL。

{
  "homepage": "https://github.com/user/project#readme"
}

3.4 bugs

问题反馈地址。

// 简单形式
{
  "bugs": "https://github.com/user/project/issues"
}

// 完整形式
{
  "bugs": {
    "url": "https://github.com/user/project/issues",
    "email": "support@example.com"
  }
}

3.5 license

包的许可证类型。

说明:npm 推荐使用 SPDX License IDSPDX License Expression。如果是自定义许可证,可使用 SEE LICENSE IN <filename>,并在包根目录包含对应的许可证文件。

// SPDX 标识符
{ "license": "MIT" }
{ "license": "Apache-2.0" }
{ "license": "GPL-3.0-only" }
{ "license": "ISC" }

// 未开源
{ "license": "UNLICENSED" }

// 多许可证(用户可选择)
{ "license": "(MIT OR Apache-2.0)" }

// 自定义/非 SPDX 许可证
{ "license": "SEE LICENSE IN LICENSE" }

补充:旧式的 licenses: [{ type, url }]license: { type, url } 写法已被 npm 标记为过时(deprecated),建议改用 SPDX 表达式。

常见许可证对比:

许可证 商业使用 修改分发 专利授权 需保留版权
MIT -
Apache-2.0
GPL-3.0-only ✓(开源)
BSD-3-Clause -
ISC -

注:上表为“快速对比”而非严格法律结论。这里的“专利授权”指许可证文本中是否包含明确的专利许可条款;MIT/BSD/ISC 通常不包含显式专利授权条款,但在不同司法辖区可能存在“默示授权/禁止反悔”等解释空间。

3.6 author 和 contributors

包的作者和贡献者信息。

// 字符串格式
{
  "author": "John Doe <john@example.com> (https://johndoe.com)"
}

// 对象格式
{
  "author": {
    "name": "John Doe",
    "email": "john@example.com",
    "url": "https://johndoe.com"
  }
}

// 贡献者列表
{
  "contributors": [
    "Jane Smith <jane@example.com>",
    {
      "name": "Bob Wilson",
      "email": "bob@example.com"
    }
  ]
}

3.7 funding

项目资助信息。

// 单一资助链接
{
  "funding": "https://opencollective.com/myproject"
}

// 对象形式
{
  "funding": {
    "type": "opencollective",
    "url": "https://opencollective.com/myproject"
  }
}

// 多个资助渠道
{
  "funding": [
    {
      "type": "github",
      "url": "https://github.com/sponsors/user"
    },
    {
      "type": "patreon",
      "url": "https://patreon.com/user"
    }
  ]
}

3.8 repository

源代码仓库地址。

// 简写形式(GitHub)
{
  "repository": "github:user/repo"
}

// 完整形式
{
  "repository": {
    "type": "git",
    "url": "https://github.com/user/repo.git"
  }
}

// Monorepo 中指定目录
{
  "repository": {
    "type": "git",
    "url": "https://github.com/user/monorepo.git",
    "directory": "packages/my-package"
  }
}

4. 入口点字段

4.1 main

指定包的主入口文件,当其他模块 require()import 包时使用。

{
  "main": "./dist/index.js"
}

4.2 browser

指定浏览器环境的入口文件,用于替代 main

{
  "main": "./dist/index.js",
  "browser": "./dist/browser.js"
}

也可以用对象形式替换特定模块:

{
  "browser": {
    "./lib/server.js": "./lib/browser.js",
    "fs": false
  }
}

4.3 module

指定 ES Module 格式的入口文件(非官方标准,但被打包工具广泛支持)。

{
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs"
}

4.4 type

指定 .js 文件的模块类型。

// ES Module(推荐新项目使用)
{
  "type": "module"
}

// CommonJS(默认值)
{
  "type": "commonjs"
}

文件扩展名与模块类型对照:

type 值 .js 文件解析为 .mjs 文件 .cjs 文件
“module” ES Module ES Module CommonJS
“commonjs” CommonJS ES Module CommonJS
未设置 CommonJS ES Module CommonJS

4.5 exports(重要)

exports 是现代包的推荐入口点配置方式,提供了比 main 更强大的功能:

基本用法:

{
  "exports": "./dist/index.js"
}

多入口点:

{
  "exports": {
    ".": "./dist/index.js",
    "./utils": "./dist/utils.js",
    "./helpers/*": "./dist/helpers/*.js"
  }
}

条件导出:

{
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs",
      "default": "./dist/index.js"
    }
  }
}

完整的条件导出配置:

{
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs",
      "default": "./dist/index.js"
    },
    "./utils": {
      "types": "./dist/utils.d.ts",
      "import": "./dist/utils.mjs",
      "require": "./dist/utils.cjs"
    },
    "./package.json": "./package.json"
  }
}

条件导出优先级(从上到下):

条件 说明
types TypeScript 类型定义(应放首位)
import ES Module 环境
require CommonJS 环境
node Node.js 环境
browser 浏览器环境
development 开发环境
production 生产环境
default 默认回退

4.6 imports

定义包内部的导入映射,使用 # 前缀。

{
  "imports": {
    "#utils": "./src/utils/index.js",
    "#config": "./src/config.js",
    "#lib/*": "./src/lib/*.js"
  }
}

在代码中使用:

// 不再需要写相对路径
import { helper } from "#utils";
import config from "#config";

条件导入:

{
  "imports": {
    "#platform": {
      "node": "./src/platform-node.js",
      "browser": "./src/platform-browser.js",
      "default": "./src/platform-default.js"
    }
  }
}

5. 文件相关字段

5.1 files

指定发布到 npm 时包含的文件。

{
  "files": ["dist", "lib", "es", "README.md", "LICENSE"]
}

始终包含的文件(无需列出):

始终排除的文件:

5.2 bin

定义可执行命令。

// 单个命令(命令名与包名相同)
{
  "name": "my-cli",
  "bin": "./bin/cli.js"
}

// 多个命令
{
  "bin": {
    "mycli": "./bin/cli.js",
    "mycli-init": "./bin/init.js"
  }
}

可执行文件要求:

#!/usr/bin/env node
// bin/cli.js 的第一行必须是 shebang
console.log("Hello from CLI!");

5.3 man

指定 man 手册页。

// 单个手册
{
  "man": "./man/doc.1"
}

// 多个手册
{
  "man": [
    "./man/myapp.1",
    "./man/myapp-config.5"
  ]
}

5.4 directories

指定项目目录结构(主要用于文档目的)。

{
  "directories": {
    "bin": "./bin",
    "lib": "./lib",
    "man": "./man",
    "doc": "./doc",
    "example": "./examples",
    "test": "./test"
  }
}

6. 脚本字段

6.1 scripts 基础

scripts 字段定义可通过 npm run 执行的命令。

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "test": "vitest",
    "lint": "eslint src",
    "format": "prettier --write src"
  }
}

执行脚本:

npm run dev
npm run build

# test/start/stop/restart 可省略 run
npm test
npm start

6.2 生命周期脚本

NPM 在特定操作时自动执行的脚本。

{
  "scripts": {
    "prepare": "husky install",
    "prepublishOnly": "npm run build && npm test",
    "preinstall": "node check-environment.js",
    "postinstall": "node setup.js"
  }
}

主要生命周期脚本:

脚本 触发时机
preinstall 安装包之前
install 安装包时
postinstall 安装包之后
prepare 安装后、发布前(常用于构建和设置 Git hooks)
prepublishOnly 仅在 npm publish 之前
prepack 打包前(tarball 创建前)
postpack 打包后
prepublish 已废弃,避免使用

6.3 pre 和 post 钩子

任何自定义脚本都可以添加 prepost 前缀钩子。

{
  "scripts": {
    "prebuild": "rm -rf dist",
    "build": "tsc",
    "postbuild": "node scripts/copy-assets.js",

    "pretest": "npm run lint",
    "test": "vitest",
    "posttest": "echo 'Tests completed!'"
  }
}

执行 npm run build 时,执行顺序为:

  1. prebuild
  2. build
  3. postbuild

6.4 常用脚本模式

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "test": "vitest",
    "test:watch": "vitest --watch",
    "test:coverage": "vitest --coverage",
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "typecheck": "tsc --noEmit",
    "clean": "rm -rf dist node_modules",
    "prepare": "husky install"
  }
}

命名规范:使用动词开头,变体用冒号分隔(如 test:watch)。


7. 依赖管理字段

7.1 dependencies

生产环境必需的依赖,会在 npm install --production 时安装。

{
  "dependencies": {
    "express": "^4.18.2",
    "lodash": "^4.17.21"
  }
}

7.2 devDependencies

仅开发环境需要的依赖,不会在生产环境安装。

{
  "devDependencies": {
    "typescript": "^5.0.0",
    "vitest": "^1.0.0",
    "eslint": "^8.0.0",
    "@types/node": "^20.0.0"
  }
}

dependencies vs devDependencies 选择指南:

依赖类型 放置位置 示例
运行时必需 dependencies express, react, lodash
构建工具 devDependencies webpack, vite, esbuild
测试框架 devDependencies jest, vitest, mocha
代码检查 devDependencies eslint, prettier
类型定义 devDependencies @types/*, typescript
文档生成 devDependencies typedoc, jsdoc

7.3 peerDependencies

声明包与宿主项目共享的依赖,避免重复安装。

{
  "name": "my-react-component",
  "peerDependencies": {
    "react": "^17.0.0 || ^18.0.0",
    "react-dom": "^17.0.0 || ^18.0.0"
  }
}

使用场景:

注意: npm 7+ 默认自动安装 peerDependencies。

7.4 peerDependenciesMeta

为 peerDependencies 提供额外元数据。

{
  "peerDependencies": {
    "react": "^18.0.0",
    "react-native": "^0.70.0"
  },
  "peerDependenciesMeta": {
    "react-native": {
      "optional": true
    }
  }
}

7.5 optionalDependencies

可选依赖,安装失败不会导致整体安装失败。

{
  "optionalDependencies": {
    "fsevents": "^2.3.2"
  }
}

代码中需要处理依赖不存在的情况:

try {
  const fsevents = require("fsevents");
  // 使用 fsevents
} catch (err) {
  // 回退方案
}

7.6 bundleDependencies

指定发布时打包到 tarball 中的依赖。

{
  "bundleDependencies": ["internal-package", "legacy-module"]
}

7.7 overrides

强制指定依赖树中某个包的版本(npm 8.3+)。

{
  "overrides": {
    // 全局覆盖
    "lodash": "4.17.21",

    // 特定依赖下的覆盖
    "webpack": {
      "terser": "5.15.0"
    },

    // 嵌套覆盖
    "react-scripts": {
      "webpack": {
        "terser": "5.15.0"
      }
    }
  }
}

Yarn 使用 resolutions

{
  "resolutions": {
    "lodash": "4.17.21",
    "webpack/terser": "5.15.0"
  }
}

7.8 版本范围语法

语法 示例 匹配范围
精确版本 1.2.3 仅 1.2.3
^ ^1.2.3 >=1.2.3 <2.0.0(主版本锁定)
~ ~1.2.3 >=1.2.3 <1.3.0(次版本锁定)
>/< >1.2.3 大于 1.2.3
>=/<= >=1.2.3 大于等于 1.2.3
- 1.2.3 - 2.0.0 >=1.2.3 <=2.0.0
x/* 1.2.x >=1.2.0 <1.3.0
\|\| ^1.0 \|\| ^2.0 1.x 或 2.x
latest latest 最新发布版本
* * 任意版本

URL 依赖:

{
  "dependencies": {
    "local-pkg": "file:../local-pkg",
    "git-pkg": "git+https://github.com/user/repo.git",
    "github-pkg": "github:user/repo#branch",
    "tarball-pkg": "https://example.com/package.tgz"
  }
}

8. 环境配置字段

8.1 engines

指定项目运行所需的 Node.js 和 npm 版本。

{
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  }
}

严格执行(需要配置):

创建 .npmrc 文件:

engine-strict=true

或配置 package.json

{
  "engines": {
    "node": ">=18.0.0"
  },
  "engineStrict": true
}

8.2 os

限制包运行的操作系统。

// 仅允许特定系统
{
  "os": ["darwin", "linux"]
}

// 排除特定系统
{
  "os": ["!win32"]
}

可用值: darwinlinuxwin32freebsdopenbsdsunosaix

8.3 cpu

限制包运行的 CPU 架构。

// 仅允许特定架构
{
  "cpu": ["x64", "arm64"]
}

// 排除特定架构
{
  "cpu": ["!arm", "!mips"]
}

可用值: x64armarm64ia32mipsppc64s390x


9. 发布配置字段

9.1 private

设置为 true 防止包被意外发布。

{
  "private": true
}

使用场景:

9.2 publishConfig

发布时使用的配置。

{
  "publishConfig": {
    "registry": "https://npm.company.com/",
    "access": "public",
    "tag": "next"
  }
}

常用配置项:

字段 说明
registry 发布目标仓库
access publicrestricted
tag 发布时的标签(默认 latest

发布作用域包为公开:

{
  "name": "@org/my-package",
  "publishConfig": {
    "access": "public"
  }
}

提示publishConfig 中的配置项也可以在项目的 .npmrc 文件中设置。例如:

registry=https://npm.company.com/
access=public

两者的区别在于:package.json 中的 publishConfig 会随包一起发布,而 .npmrc 通常用于本地或 CI 环境配置,且可以包含敏感信息(如 token),不建议提交到版本控制。


10. 工作空间配置

10.1 workspaces 基础

workspaces 用于配置 Monorepo,管理多个相关包。

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": ["packages/*", "apps/*"]
}

目录结构:

my-monorepo/
├── package.json
├── packages/
│   ├── core/
│   │   └── package.json
│   ├── utils/
│   │   └── package.json
│   └── cli/
│       └── package.json
└── apps/
    ├── web/
    │   └── package.json
    └── api/
        └── package.json

10.2 Monorepo 配置示例

根 package.json:

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": ["packages/*", "apps/*"],
  "scripts": {
    "build": "npm run build --workspaces",
    "test": "npm run test --workspaces --if-present"
  }
}

子包 package.json:

{
  "name": "@org/core",
  "version": "1.0.0",
  "main": "./dist/index.js",
  "dependencies": {
    "@org/utils": "workspace:*"
  }
}

10.3 工作空间命令

# 在所有工作空间运行脚本
npm run build --workspaces

# 在特定工作空间运行
npm run build -w @org/core

# 添加依赖到特定工作空间
npm install lodash -w @org/utils

# 运行脚本(跳过没有该脚本的包)
npm run test --workspaces --if-present

11. 其他字段

11.1 config

设置脚本中可用的环境变量。

{
  "name": "my-package",
  "config": {
    "port": "8080",
    "host": "localhost"
  },
  "scripts": {
    "start": "node server.js"
  }
}

在脚本中访问:

// 通过 npm_package_config_ 前缀访问
const port = process.env.npm_package_config_port; // "8080"

用户可覆盖配置:

npm config set my-package:port 3000

11.2 sideEffects

告知打包工具(如 webpack)包是否有副作用,用于 Tree Shaking 优化。

// 无副作用,可以安全 Tree Shake
{
  "sideEffects": false
}

// 指定有副作用的文件
{
  "sideEffects": [
    "*.css",
    "*.scss",
    "./src/polyfills.js"
  ]
}

11.3 types / typings

指定 TypeScript 类型定义入口文件。

{
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts"
}

// 或使用 typings(等效)
{
  "typings": "./dist/index.d.ts"
}

配合 exports 使用:

{
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  }
}

12. 项目配置示例

注意:以下示例仅展示各类项目的核心配置,实际项目可根据需要扩展。

12.1 Web 应用项目

{
  "name": "my-web-app",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "test": "vitest",
    "lint": "eslint src",
    "prepare": "husky install"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "vite": "^5.0.0",
    "typescript": "^5.0.0"
  }
}

关键点private: true 防止意外发布。

12.2 NPM 库项目(双模式)

{
  "name": "@org/utils",
  "version": "1.0.0",
  "license": "MIT",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    }
  },
  "files": ["dist"],
  "sideEffects": false,
  "scripts": {
    "build": "tsup",
    "prepublishOnly": "npm run build && npm test"
  },
  "publishConfig": {
    "access": "public"
  }
}

关键点exports 实现条件导出,sideEffects: false 启用 Tree Shaking。

12.3 CLI 工具项目

{
  "name": "my-cli",
  "version": "1.0.0",
  "type": "module",
  "bin": {
    "my-cli": "./dist/cli.js"
  },
  "files": ["dist"],
  "dependencies": {
    "commander": "^11.0.0"
  },
  "engines": {
    "node": ">=18.0.0"
  }
}

关键点bin 定义可执行命令,入口文件需添加 #!/usr/bin/env node

12.4 Monorepo 根配置

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": ["packages/*", "apps/*"],
  "scripts": {
    "build": "npm run build --workspaces",
    "test": "npm run test --workspaces --if-present"
  }
}

关键点workspaces 定义子包路径,--if-present 跳过无对应脚本的包。


13. 最佳实践

13.1 版本管理

  1. 遵循语义化版本
    • 破坏性变更 → 升级主版本
    • 新功能(向后兼容)→ 升级次版本
    • Bug 修复 → 升级修订版本
  2. 使用版本管理工具

    # 使用 npm version
    npm version patch  # 1.0.0 → 1.0.1
    npm version minor  # 1.0.0 → 1.1.0
    npm version major  # 1.0.0 → 2.0.0
    
    # 或使用 changesets(推荐用于 Monorepo)
    npx changeset
    
  3. 预发布版本标签
    npm publish --tag beta
    npm publish --tag next
    

13.2 依赖管理

  1. 定期更新依赖

    # 检查过期依赖
    npm outdated
    
    # 使用 npm-check-updates
    npx npm-check-updates
    npx npm-check-updates -u
    
  2. 锁定文件
    • 始终提交 package-lock.json
    • CI 环境使用 npm ci 而非 npm install
  3. 依赖分类原则
    • 运行时依赖 → dependencies
    • 开发工具 → devDependencies
    • 共享依赖 → peerDependencies
  4. 安全审计
    npm audit
    npm audit fix
    

13.3 脚本编写

  1. 使用跨平台工具

    {
      "scripts": {
        // 使用 rimraf 替代 rm -rf
        "clean": "rimraf dist",
        // 使用 cross-env 设置环境变量
        "build": "cross-env NODE_ENV=production webpack"
      }
    }
    
  2. 脚本命名规范
    • 使用动词开头:buildtestlint
    • 变体使用冒号分隔:test:watchbuild:prod
    • 保持一致性
  3. 组合脚本
    {
      "scripts": {
        "validate": "npm run lint && npm run typecheck && npm run test"
      }
    }
    

13.4 发布前检查清单


14. 常见问题与解决方案

Q1: 如何解决依赖冲突?

// 使用 overrides(npm 8+)
{
  "overrides": {
    "problematic-package": "1.2.3"
  }
}
# 或使用 --force 安装
npm install --force

# 使用 --legacy-peer-deps 忽略 peerDependencies 冲突
npm install --legacy-peer-deps

Q2: 如何处理 ESM 和 CommonJS 兼容性?

{
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  }
}

Q3: 如何排除文件发布?

创建 .npmignore 文件:

src/
test/
*.test.js
.eslintrc
tsconfig.json

或使用 files 字段白名单方式(推荐):

{
  "files": ["dist", "README.md"]
}

Q4: 如何本地测试包发布内容?

# 查看将要发布的文件
npm pack --dry-run

# 创建 tarball 检查内容
npm pack
tar -tzf my-package-1.0.0.tgz

Q5: 如何处理 monorepo 中的内部依赖?

{
  "dependencies": {
    "@org/utils": "workspace:*"
  }
}

Q6: 如何指定不同环境的脚本?

{
  "scripts": {
    "start": "node index.js",
    "start:dev": "nodemon index.js",
    "start:prod": "NODE_ENV=production node index.js"
  }
}

Q7: exportsmain 应该同时使用吗?

推荐同时设置,以兼容老版本 Node.js:

{
  "main": "./dist/index.js",
  "exports": {
    ".": "./dist/index.js"
  }
}

Q8: 如何发布到私有仓库?

{
  "publishConfig": {
    "registry": "https://npm.your-company.com/"
  }
}

或在 .npmrc 中配置:

@your-org:registry=https://npm.your-company.com/
//npm.your-company.com/:_authToken=${NPM_TOKEN}

15. 总结

package.json 是 Node.js 项目的核心配置文件,掌握其配置对于高效开发至关重要。

核心要点回顾

场景 关键字段 注意事项
包标识 name, version 遵循命名规则和语义化版本
模块入口 main, exports, type 优先使用 exports 实现条件导出
依赖管理 dependencies, devDependencies, peerDependencies 正确分类,定期审计
脚本命令 scripts 善用生命周期钩子和命名规范
发布控制 private, files, publishConfig 发布前检查包含文件
Monorepo workspaces 使用 workspace:* 协议管理内部依赖

最佳实践速查


16. 参考资源