关于 rslib-modern-package
用于创建、现代化改造或审查 Rslib JavaScript 和 TypeScript 库的技能。它以详细标准检查公共 API、类型、依赖、发布流程和已发布构件。
主要功能
- 01ESM 优先的包设计建议
- 02明确设置 package.json exports
- 03TypeScript 声明与严格性检查
- 04依赖和副作用审查
- 05打包构件与发布流程验证
适用场景
- 01创建新的 Rslib 库
- 02现代化改造现有 JS/TS 包
- 03审查包的导出与类型声明
- 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 保留软件包的不变量。
工作流
-
先检查软件包契约
- 阅读
package.json、锁文件/软件包管理器、rslib.config.*、tsconfig*、CI/发布配置、README.md、AGENTS.md,以及现有的dist输出。 - 确定软件包类型:Node.js 工具、浏览器库、同构工具、CLI、UI/组件库、框架插件、SDK 或适配器。
- 列出支持的运行时、当前入口点、深层导入、运行时依赖、对等依赖、可选集成、带副作用的文件,以及要发布的文件。
- 更改软件包结构时,尽早运行
npm pack --dry-run,以真实的压缩包内容作为审查依据。
- 阅读
-
明确界定目标环境
- 不要在未明确界定的情况下声称“支持现代环境”。
- 选择
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/浏览器、未文档化的深层导入、默认/具名导出的形式、依赖项是打包还是外置的行为,以及导入副作用。
-
优先使用纯 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 内置模块说明符。
- 新软件包应使用
-
将
exports设为公共 API- 将
package.json#exports视为产品契约。 - 仅导出用户应该导入的路径。
- 不要通过导出
./dist/*允许诸如pkg/dist/foo.js这样的导入。这会让生成的输出布局成为公共 API 的一部分,并导致内部文件移动也变成破坏性变更。 - 应仅公开有意提供的路径,例如
pkg和pkg/foo.js,并将其映射到dist中的实际文件。 - 统一子路径风格:要么都带扩展名,例如
./foo.js,要么都不带扩展名。当浏览器导入映射很重要时,优先选择带扩展名的路径。 - 在条件导出中,将
"types"放在首位。 - 为较旧的包添加
exports可能会造成破坏性变更,因为未声明的深层导入将无法继续使用。 - 仅在使用者确实需要包元数据时,才添加
./package.json。
- 将
-
设计精简的 API
- 对于包含多个 API 的包,优先使用命名导出。
- 避免使用将所有函数汇集到一个对象中的默认导出。
- 公共函数应数量少、稳定、命名清晰,并通过语义化版本维护。
- 除非属于契约的一部分,否则应将内部类型、缓存、辅助函数、适配器细节和错误内部实现保持为私有。
- 避免在导入期间执行顶层操作:文件扫描、网络调用、计时器、进程修改、全局注册、DOM 访问、原型修改,或带有副作用的环境检测。
- 可能会被取消的异步 API 应接受
AbortSignal。 - 优先使用稳定的错误类、错误代码或带类型的错误结构,而不是匹配字符串。
-
将 Rslib 用作实现方式,而不是完整标准
- 有关 Rslib 配置的详细指南,请使用
rslib-best-practices技能。 - 在此技能中,只需检查 Rslib 输出、声明文件、
package.json#exports、files、依赖项和文档是否符合现代包契约。 - 保持 Rslib 配置精简且有明确意图;避免增加不会改善包契约的构建复杂性。
- 有关 Rslib 配置的详细指南,请使用
-
让依赖保持精简且有明确用途
- 从平台 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。
-
让 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来掩盖包类型的问题。 - 像使用者那样测试声明文件,尤其是在使用子路径导出时。
-
确保
sideEffects准确无误- 仅当导入包文件不会产生顶层副作用时,才使用
sideEffects: false。 - 如果存在 CSS、polyfill、注册操作、全局监听器、原型更改或其他导入时变更,请改为列出存在副作用的文件。
- 不要为了减小打包体积而设置
sideEffects: false;不正确的值可能会移除必需的 CSS 或初始化代码。 - 不要仅仅因为导入了文件就更改全局状态。如果需要初始化,请提供显式的
setup()或install()函数,让用户自行调用。
- 仅当导入包文件不会产生顶层副作用时,才使用
-
让
package.json成为权威配置- 现代包必需的配置:
"type": "module"、显式的exports、正确的声明文件、files允许列表、准确的sideEffects、合理的engines和发布脚本。 - 如果存在,请在
files中包含 README.md、AGENTS.md 和 LICENSE。 files应防止测试、fixture、私有文档、构建缓存、本地配置和大型生成产物泄漏到 tarball 中。- 除非有兼容性证据要求,否则避免使用过时的
main/module字段;如果保留,这些字段必须与exports一致。 - 确保运行时依赖字段准确。若包只能在本地运行,是因为运行时依赖被列在
devDependencies中,那么这个包就是有问题的。
- 现代包必需的配置:
-
验证发布产物
- 运行常规的 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 执行,以及每个公共子路径导出。
- 运行常规的 lint、类型检查、测试和
-
发布前准备 README.md 和 AGENTS.md
- 发布或更新包之前,始终检查这两个文件是否都存在。
- 如果缺少任一文件,建议补上;对于实现任务,除非用户另有要求,否则创建简洁版本。
- README.md 应包含:包名称、一句话用途说明、安装和用法、主要功能或 API 链接、支持的环境、文档及相关链接、更新日志或贡献指南链接,以及许可证。
- AGENTS.md 应包含:技术栈、包契约、常用命令、源码布局、代码风格、验证命令和发布检查清单。
- 确保这两个文件与
package.json#exports、支持的运行时和实际的 Rslib 输出保持一致。
-
以供应链安全为原则发布
- 遵循 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/可信发布。
文档
- 如需查看最新的 Rslib 文档,请阅读 https://rslib.rs/llms.txt
- 为 CommonJS 使用者提供 ESM: https://nodejs.github.io/package-examples/04-cjs-esm-interop/shipping-esm-for-cjs/
评论
支持 Markdown