mcpField
R
rslib-modern-package

rslib-modern-package

github.com/rstackjs开发97115 次安装6 天前更新
代码仓库

关于 rslib-modern-package

用于创建、现代化改造或审查 Rslib JavaScript 和 TypeScript 库的技能。它以详细标准检查公共 API、类型、依赖、发布流程和已发布构件。

主要功能

  1. 01ESM 优先的包设计建议
  2. 02明确设置 package.json exports
  3. 03TypeScript 声明与严格性检查
  4. 04依赖和副作用审查
  5. 05打包构件与发布流程验证

适用场景

  1. 01创建新的 Rslib 库
  2. 02现代化改造现有 JS/TS 包
  3. 03审查包的导出与类型声明
  4. 04发布前检查软件包

安装

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

$npx skills add https://github.com/rstackjs/agent-skills --skill rslib-modern-package

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

详细介绍

Rslib 现代化软件包

在创建新的 Rslib 库、使现有 JS/TS 软件包现代化,或根据一套主张鲜明的现代库标准审查软件包时,请使用此技能。

此技能有明确主张:它描述了推荐的现代软件包契约;当破坏性变更能让软件包更简单、更安全、更易于现代使用者使用时,也可能会建议采用这些变更。

标准

新 JS/TS 库的默认建议:

  • ESM 优先,最好使用纯 ESM。
  • 严格的 TypeScript 和正确的声明文件。
  • 通过 package.json#exports 明确公开 API。
  • 小巧的具名导出 API 表面。
  • 尽量少的运行时依赖,但不把零依赖奉为教条。
  • 输出体积小、可进行摇树优化,并准确设置 sideEffects。
  • 清晰划分依赖:运行时依赖、对等依赖、可选依赖和开发依赖不可互换。
  • 对发布的软件包进行产物测试,而不只是测试源文件。
  • 发布流程应自动化、可追溯,并遵循 SemVer。
  • README.md 面向人类说明用法;AGENTS.md 为后续 Agent 保留软件包的不变量。

工作流

  1. 先检查软件包契约

    • 阅读 package.json、锁文件/软件包管理器、rslib.config.*、tsconfig*、CI/发布配置、README.md、AGENTS.md,以及现有的 dist 输出。
    • 确定软件包类型:Node.js 工具、浏览器库、同构工具、CLI、UI/组件库、框架插件、SDK 或适配器。
    • 列出支持的运行时、当前入口点、深层导入、运行时依赖、对等依赖、可选集成、带副作用的文件,以及要发布的文件。
    • 更改软件包结构时,尽早运行 npm pack --dry-run,以真实的压缩包内容作为审查依据。
  2. 明确界定目标环境

    • 不要在未明确界定的情况下声称“支持现代环境”。
    • 选择 engines 前,先确认当前 Node.js 发布计划。
    • 截至 2026 年 5 月 9 日,Node.js 22 和 24 是 LTS 版本,Node.js 20 已 EOL。对于新的 Node.js 软件包,建议设置 engines.node >=22,除非确有使用者需要支持更旧的运行时。
    • 浏览器软件包应说明是否需要原生 ESM、打包器、Workers 支持、SSR 兼容性、DOM API、CSS 处理,或特定的浏览器基线。
    • 兼容性范围缩减属于破坏性变更:包括旧版 Node.js/浏览器、未文档化的深层导入、默认/具名导出的形式、依赖项是打包还是外置的行为,以及导入副作用。
  3. 优先使用纯 ESM,但说明兼容性代价

    • 新软件包应使用 "type": "module" 和 ESM 源码/输出。
    • Rslib 的默认格式是 ESM;除非有明确理由添加其他格式,否则保留此默认设置。
    • 应根据真实使用者和支持的运行时评估兼容性,而不是假定所有历史模块格式都必须保留。
    • 现代 Node.js 可通过 require(esm) 从 CommonJS 加载同步 ESM;不要假定 CJS 使用者始终需要单独的 CJS 构建。
    • 如果依赖 require(esm) 兼容性,请说明并测试其限制:支持的 Node.js 版本、加载图中不得包含顶层 await、命名空间对象的返回形式、默认导出的行为,以及 CJS/ESM 循环依赖的限制。
    • 优先使用 node:fs/promises 等 Node.js 内置模块说明符。
  4. 将 exports 设为公共 API

    • 将 package.json#exports 视为产品契约。
    • 仅导出用户应该导入的路径。
    • 不要通过导出 ./dist/* 允许诸如 pkg/dist/foo.js 这样的导入。这会让生成的输出布局成为公共 API 的一部分,并导致内部文件移动也变成破坏性变更。
    • 应仅公开有意提供的路径,例如 pkg 和 pkg/foo.js,并将其映射到 dist 中的实际文件。
    • 统一子路径风格:要么都带扩展名,例如 ./foo.js,要么都不带扩展名。当浏览器导入映射很重要时,优先选择带扩展名的路径。
    • 在条件导出中,将 "types" 放在首位。
    • 为较旧的包添加 exports 可能会造成破坏性变更,因为未声明的深层导入将无法继续使用。
    • 仅在使用者确实需要包元数据时,才添加 ./package.json。
  5. 设计精简的 API

    • 对于包含多个 API 的包,优先使用命名导出。
    • 避免使用将所有函数汇集到一个对象中的默认导出。
    • 公共函数应数量少、稳定、命名清晰,并通过语义化版本维护。
    • 除非属于契约的一部分,否则应将内部类型、缓存、辅助函数、适配器细节和错误内部实现保持为私有。
    • 避免在导入期间执行顶层操作:文件扫描、网络调用、计时器、进程修改、全局注册、DOM 访问、原型修改,或带有副作用的环境检测。
    • 可能会被取消的异步 API 应接受 AbortSignal。
    • 优先使用稳定的错误类、错误代码或带类型的错误结构,而不是匹配字符串。
  6. 将 Rslib 用作实现方式,而不是完整标准

    • 有关 Rslib 配置的详细指南,请使用 rslib-best-practices 技能。
    • 在此技能中,只需检查 Rslib 输出、声明文件、package.json#exports、files、依赖项和文档是否符合现代包契约。
    • 保持 Rslib 配置精简且有明确意图;避免增加不会改善包契约的构建复杂性。
  7. 让依赖保持精简且有明确用途

    • 从平台 API 入手,而不是先搜索依赖项。
    • 当运行时支持时,优先使用内置功能:URL、URLSearchParams、Intl、fetch、AbortController、structuredClone、crypto.randomUUID、Web Streams、TextEncoder、TextDecoder、node:fs/promises 和 node:crypto。
    • 如果小型运行时依赖能降低维护风险或实现复杂度,则可以使用。
    • 避免为了使用一两个辅助函数而引入大型工具包。
    • 评估依赖项的 ESM 支持、exports、类型、传递依赖数量、包大小、许可证、维护活跃度、安全记录、安装脚本、副作用、原生安装脆弱性,以及是否支持细粒度导入。
    • 将必需的运行时包放入 dependencies。
    • 将由宿主拥有的框架和工具链放入 peerDependencies,例如 React、Vue、Svelte、Rspack、Rsbuild、webpack、TypeScript 和框架运行时。
    • 保持 peer 版本范围合理宽泛;除非确有需要,否则不要将 peer 固定到补丁版本。
    • 将构建工具、测试工具、类型工具、文档工具以及 Rsbuild/Rspack 插件放入 devDependencies。
    • 对可选集成,使用 optionalDependencies,或通过 peerDependenciesMeta 声明可选 peer。
  8. 让 TypeScript 保持严格检查并面向包构建

    • 对 TS 库,优先使用 TypeScript 源码;否则使用高质量的 JSDoc,并生成声明文件。
    • 使用 TypeScript 6 或 tsgo 时代的默认设置时,严格检查可能已经启用;请保留此默认设置,不要将其关闭。对于较旧的 TypeScript 版本或继承的配置,请显式设置 strict: true。
    • 在 Rslib 项目中,如果项目可以使用 tsgo,可考虑启用 lib.dts.tsgo 以加快声明文件生成。
    • 让 module 和 moduleResolution 与声明文件的生成方式以及使用者解析包的方式保持一致;在合适的工具链中,NodeNext 和 bundler 风格的解析方式都有效。
    • 使用 verbatimModuleSyntax,明确标记仅用于类型的导入和导出。
    • 在实际可行时使用 isolatedDeclarations,让导出的 API 足够明确,以便面向声明文件的工具处理。
    • 生成声明文件;在需要编辑器导航时使用声明映射文件。
    • 对仅用于类型的依赖使用 import type 和 export type。
    • 不要依赖使用者设置 skipLibCheck 来掩盖包类型的问题。
    • 像使用者那样测试声明文件,尤其是在使用子路径导出时。
  9. 确保 sideEffects 准确无误

    • 仅当导入包文件不会产生顶层副作用时,才使用 sideEffects: false。
    • 如果存在 CSS、polyfill、注册操作、全局监听器、原型更改或其他导入时变更,请改为列出存在副作用的文件。
    • 不要为了减小打包体积而设置 sideEffects: false;不正确的值可能会移除必需的 CSS 或初始化代码。
    • 不要仅仅因为导入了文件就更改全局状态。如果需要初始化,请提供显式的 setup() 或 install() 函数,让用户自行调用。
  10. 让 package.json 成为权威配置

    • 现代包必需的配置:"type": "module"、显式的 exports、正确的声明文件、files 允许列表、准确的 sideEffects、合理的 engines 和发布脚本。
    • 如果存在,请在 files 中包含 README.md、AGENTS.md 和 LICENSE。
    • files 应防止测试、fixture、私有文档、构建缓存、本地配置和大型生成产物泄漏到 tarball 中。
    • 除非有兼容性证据要求,否则避免使用过时的 main/module 字段;如果保留,这些字段必须与 exports 一致。
    • 确保运行时依赖字段准确。若包只能在本地运行,是因为运行时依赖被列在 devDependencies 中,那么这个包就是有问题的。
  11. 验证发布产物

    • 运行常规的 lint、类型检查、测试和 rslib build。
    • 对构建后的 ESM 输出进行冒烟测试。
    • 当公共 API 涉及大量类型时,运行类型测试。
    • 运行 npm pack --dry-run 并检查包含的文件。
    • 在 Rslib 中,优先使用 rsbuild-plugin-publint 在构建后运行 publint;也可使用 npx publint 作为 CLI 后备方案。
    • 在 Rslib 中,发布声明文件时,优先使用 rsbuild-plugin-arethetypeswrong 在构建后运行 Are The Types Wrong;也可使用 npx --yes @arethetypeswrong/cli --pack . 作为 CLI 后备方案。
    • 对重要的包,将打包后的 tarball 安装到干净的使用者 fixture 中。
    • 测试 ESM 导入、浏览器/组件库的 bundler 导入、bin 包的 CLI 执行,以及每个公共子路径导出。
  12. 发布前准备 README.md 和 AGENTS.md

    • 发布或更新包之前,始终检查这两个文件是否都存在。
    • 如果缺少任一文件,建议补上;对于实现任务,除非用户另有要求,否则创建简洁版本。
    • README.md 应包含:包名称、一句话用途说明、安装和用法、主要功能或 API 链接、支持的环境、文档及相关链接、更新日志或贡献指南链接,以及许可证。
    • AGENTS.md 应包含:技术栈、包契约、常用命令、源码布局、代码风格、验证命令和发布检查清单。
    • 确保这两个文件与 package.json#exports、支持的运行时和实际的 Rslib 输出保持一致。
  13. 以供应链安全为原则发布

    • 遵循 SemVer,并记录破坏性变更。
    • 维护用户可见变更的更新日志。
    • 使用预发布版本和 dist-tag 发布 beta/next 渠道。
    • 优先通过 CI 发布,并使用 npm provenance 或可信发布。
    • 如果可以使用可信发布,避免使用长期有效的发布令牌。
    • 请注意,已发布的包名/版本组合无法安全地重复使用。

审查红旗

  • 缺少 exports,指向 Rslib 未生成的文件,或允许通过 pkg/dist/foo.js 这类路径进行公开导入。
  • module/main 字段与 exports 不一致。
  • 类型声明与运行时入口不匹配。
  • 运行时依赖意外地只列在 devDependencies 中。
  • React/Vue/Svelte/Rspack/Rsbuild/webpack/TypeScript 被打包或放入 dependencies,而它们本应是 peer 依赖。
  • 设置了 sideEffects: false,但同时导入 CSS、polyfill、全局注册项、全局监听器或原型修改。
  • 包在没有充分理由的情况下包含安装脚本。
  • 顶层导入会读取用户文件、启动计时器、访问网络、修改全局对象,或假定存在 window/process。
  • 发布的 tarball 包含私有源码映射、对使用者无用的测试/夹具、大型生成文档、本地配置密钥或构建缓存。

检查清单

  • 明确列出支持的环境。
  • 包以 ESM 为优先,最好只使用 ESM。
  • package.json 中包含 "type": "module"。
  • 在 exports 中声明公开入口。
  • 不会意外依赖未声明的深层导入。
  • Rslib 输出、类型声明、exports 和 files 相互一致。
  • 已启用 TypeScript 严格模式。
  • 已生成并验证类型声明。
  • 运行时依赖合理且精简。
  • 宿主框架/工具链作为 peer 依赖。
  • 构建/测试/类型检查/文档工具作为开发依赖。
  • sideEffects 设置准确。
  • 已检查 npm pack --dry-run 的结果。
  • publint 检查通过。
  • 如果随包发布了类型声明,Are The Types Wrong 检查通过。
  • 构建后的 ESM 冒烟测试通过。
  • README.md 存在。
  • AGENTS.md 存在。
  • 发布流程采用 SemVer、更新日志,并在可用时使用 provenance/可信发布。

文档

评论

支持 Markdown