mcpField
N
npm-package

npm-package

github.com/jwynia开发179331 次安装35 周前更新
代码仓库

关于 npm-package

面向单包 npm 库开发与发布的技能,以 Bun 为主要工具链,涵盖项目配置、兼容性、测试和发布流程。

主要功能

  1. 01生成 npm 包项目骨架
  2. 02配置 ESM 或 CJS/ESM 双格式输出
  3. 03设置 TypeScript 声明与导出
  4. 04配置 Biome、ESLint 和 Vitest
  5. 05准备 npm 发布流程

适用场景

  1. 01从头创建 npm 库
  2. 02修复模块互操作或类型声明问题
  3. 03配置包检查与测试
  4. 04发布前检查包配置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jwynia/agent-skills --skill npm-package

安装后在 Claude Code 中输入/npm-package确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

reference/
esm-cjs-guide.md
publishing-workflow.md
strict-typescript.md
scripts/
scaffold.ts
templates/
biome.json
bunup.config.ts
eslint.config.ts
gitignore
package.json.hbs
tsconfig.json
vitest.config.ts
templates/src/
index.test.ts.hbs
index.ts.hbs

详细介绍

npm 包开发(Bun 优先)

使用 Bun 作为主要运行时和工具链来构建并发布 npm 包,确保产物能在 npm 包的所有使用场景中正常工作。

何时使用此技能

适用于:

  • 从头创建新的 npm 库包
  • 为现有包配置构建、测试和 lint 工具
  • 修复 CJS/ESM 互操作、导出映射或 TypeScript 声明问题
  • 将包发布到 npm
  • 审查或改进包配置

不适用于:

  • 构建可通过 npx 执行的 CLI 工具(使用 npx-cli 技能)
  • 构建应用程序(而非已发布的包)
  • 在 monorepo 中工作(此技能面向单包仓库)

工具链

事项工具原因
运行时 / 包管理器Bun安装、运行和转译速度快
打包工具Bunup原生支持 Bun、双格式输出、生成 .d.ts
类型声明Bunup(通过 tsc)集成在构建流程中
TypeScriptmodule: "nodenext"、strict: true + 额外选项确保已发布代码的正确性
格式化 + 基础 lintBiome v2比 ESLint 快 10-25 倍,使用单一工具
类型感知 lintESLint + typescript-eslint提供 40 多条 Biome 无法实现的类型感知规则
测试Vitest测试隔离、成熟的模拟功能和覆盖率
版本管理Changesets基于文件、明确、适用于 monorepo
发布npm publish --provenance可信发布 / OIDC

搭建新包的脚手架

运行脚手架脚本,生成完整项目:

bun run <skill-path>/scripts/scaffold.ts ./my-package \
  --name my-package \
  --description "What this package does" \
  --author "Your Name" \
  --license MIT

选项:

  • --dual — 生成双 CJS/ESM 输出(默认:仅 ESM)
  • --no-eslint — 跳过 ESLint,仅使用 Biome

然后安装依赖:

cd my-package
bun install
bun add -d bunup typescript vitest @vitest/coverage-v8 @biomejs/biome @changesets/cli
bun add -d eslint typescript-eslint  # unless --no-eslint

项目结构

my-package/
├── src/
│   ├── index.ts            # Package entry point — all public API exports here
│   └── index.test.ts       # Tests co-located with source
├── dist/                   # Built output (gitignored, included in published tarball)
├── .changeset/
│   └── config.json
├── package.json
├── tsconfig.json
├── bunup.config.ts
├── biome.json
├── eslint.config.ts        # Type-aware rules only
├── vitest.config.ts
├── .gitignore
├── README.md
└── LICENSE

关键配置细节

修改任何配置前,请阅读以下参考文档。这些文档解释了各项决策背后的原因,以及可能导致隐蔽故障的注意事项:

关键规则(不可妥协)

违反以下规则会导致已发布包中最常见、影响最严重的问题。请务必遵守,不得例外。

包配置
  1. 始终在 package.json 中使用 "type": "module"。 仅 ESM 是正确的默认选择。所有受支持的 Node.js 版本都支持 require(esm)。

  2. 始终使用 exports 字段,不要使用 main。 main 已过时。exports 可精确控制使用者能够访问的内容。

  3. 每个 exports 块中,types 必须是第一个条件。 否则 TypeScript 会静默地无法解析类型。

  4. 始终导出 "./package.json": "./package.json"。 许多工具需要访问 package.json,而 exports 会完全封装包的内容。

  5. 在 package.json 中使用 files: ["dist"]。 白名单方式可防止意外发布机密信息。切勿使用 .npmignore。

  6. 每次发布前都运行 npm pack --dry-run。 确认压缩包恰好包含你想要发布的内容。

TypeScript
  1. 已发布的包应使用 module: "nodenext"。 不要使用 "bundler"。符合 nodenext 要求的代码可在任何地方运行,反之则不然。

  2. strict: true 不可妥协。 否则,你的 .d.ts 文件可能包含会导致使用 strict 模式的使用者报错的类型。

  3. 启用 noUncheckedIndexedAccess。 捕获因未检查的数组或对象访问导致的真实运行时错误。

  4. 发布 declarationMap: true。 让使用者能够通过“转到定义”定位到原始源代码。

  5. 已发布的包中不要使用路径别名(paths)。 tsc 不会在生成的代码中重写它们,使用者将无法解析这些别名。

代码质量
  1. 禁止使用 any。 使用 unknown 并进行收窄。只有在确实无法避免时,才使用 // biome-ignore suspicious/noExplicitAny: <reason> 抑制检查,并始终说明原因。

  2. 优先使用命名导出,而非默认导出。 默认导出在 CJS/ESM 边界上的行为有所不同。

  3. 类型专用导入一律使用 import type。 verbatimModuleSyntax 和 Biome 的 useImportType 规则都会强制执行此项要求。

构建
  1. 使用 Bunup 构建,并设置 format: ['esm'](双格式构建则设置为 ['esm', 'cjs'])。Bunup 会处理 .d.ts 生成、外部依赖检测以及正确的文件扩展名。

  2. 在 package.json 中将 engines.node 设为 >=20.19.0。这会注明最低支持的 Node.js 版本(首个支持稳定 require(esm) 的 LTS 版本)。

测试
  1. 使用 Vitest,而非 bun:test。 bun:test 缺乏测试隔离机制,模块模拟会在文件之间泄漏。Vitest 会在各自的工作线程中运行每个测试文件。

  2. 设置覆盖率阈值(分支、函数、行和语句覆盖率均 ≥ 80%)。在 vitest.config.ts 中强制执行。

开发工作流

# Write code and tests
bun run test:watch    # Vitest watch mode

# Check everything
bun run lint          # Biome + ESLint
bun run typecheck     # tsc --noEmit
bun run test          # Vitest run

# Build
bun run build         # Bunup → dist/

# Prepare release
bunx changeset        # Create changeset describing changes
bunx changeset version  # Bump version, update CHANGELOG

# Publish
bun run release       # Build + npm publish --provenance

添加子路径导出

当包需要公开多个入口点时:

  1. 添加源文件:src/utils.ts
  2. 将其添加到 bunup.config.ts 的 entry 中:entry: ['src/index.ts', 'src/utils.ts']
  3. 将其添加到 package.json 的 exports 中:
{
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    },
    "./utils": {
      "types": "./dist/utils.d.ts",
      "default": "./dist/utils.js"
    },
    "./package.json": "./package.json"
  }
}

提醒: 添加或移除导出路径属于 semver 主版本变更。

切换到 CJS/ESM 双格式输出

如果消费者需要支持 Node.js < 20.19.0 的 CJS:

  1. 更新 bunup.config.ts:format: ['esm', 'cjs']
  2. 更新 package.json 的 exports,加入 module-sync、import 和 require 条件
  3. 有关 exports 映射的确切结构,请参阅 reference/esm-cjs-guide.md

Bun 特有注意事项

  • bun build 不会生成 .d.ts 文件。 使用 Bunup(它会委托给 tsc),或单独运行 tsc --emitDeclarationOnly。
  • bun build 的 CJS 输出仍处于实验阶段。 对于可发布到 npm 的 CJS,始终使用 target: "node"。target: "bun" 会生成 Bun 专用包装器。
  • bun build 不会降级语法。 现代 ES2022+ 语法会原样发布。若要面向较旧的运行时,还需进行额外转译。
  • bun publish 不支持 --provenance。 如需进行来源证明签名,请使用 npm publish。
  • bun publish 使用 NPM_CONFIG_TOKEN,而非 NODE_AUTH_TOKEN。可能需要调整 CI 流水线。

评论

支持 Markdown