JSR:JavaScript 注册表
由 Deno 团队创建的新 JavaScript 包注册表 JSR,旨在提供一个以 TypeScript 为先、仅面向 ESM 的 npm 替代方案,同时仍可与现有 npm 包和工具互操作。支持者强调其内置类型处理、自动文档、来源证明,以及与现代运行时更紧密的集成,相比老旧且由 Microsoft 控制的 npm 注册表更具优势。批评者则质疑是否需要另一个中心化注册表,担心生态碎片化、命名与治理问题,并对诸如惩罚大量类型推断、在缺乏正式标准的情况下高度依赖 TypeScript 等设计选择表示担忧。
JSR 的目的与设计
- 面向 JavaScript/TypeScript 的新中心化注册表,由 Deno 团队构建,但目标是与运行时无关。
- 其动机来自 Deno 中基于 URL 的导入问题:依赖重复(没有基于 semver 的去重)以及可能消失的脆弱 URL。
- 重点放在 TypeScript 和 ESM:你发布 TS 源码,JSR 负责转译、.d.ts 生成、文档以及跨运行时构建。
- Deno 仍支持 HTTPS 导入,但 JSR 被定位为更稳健的默认选择。
TypeScript、仅语法方案,以及“慢类型”
- 注册表依赖 TypeScript 语法,而不是完整类型系统;不进行基于 TSC 的分析。
- 为了让类型操作快速且稳定,它强烈鼓励显式的公共 API 类型,并限制推断(“慢类型”会得到较低评分,但仍然可以发布)。
- 文中提到即将到来的 TS 选项,如
isolatedDeclarations和编辑器快速修复,可减轻这种摩擦。
与 npm 和工具链的关系
- JSR 是注册表,不是包管理器;它通过类似 npm 的 API 和
node_modules与现有工具集成。 - JSR 模块可以依赖 npm 模块,反之亦然;还提供一个 npm 兼容层,为 Node 输出 JS + .d.ts。
- 对“npm 的超集”等营销措辞存在一些困惑;几位评论者建议使用更清晰的说法,如“增补式”或“互补式”。
- 现有的 Deno 到 npm 工作流(例如 dnt)短期内仍然可行;从长远看,JSR 旨在直接覆盖这一用例。
治理、命名空间与不可变性
- Scope 经过筛选;显而易见的品牌 scope 可以重新分配给经过验证的所有者。
- 过去的版本保持不可变并持续可用;新的 scope 所有者可以在同一 scope 下发布更新版本。
- 一些人认为这是在重复过去注册表中的命名纷争;另一些人则提议使用基于 DNS 或 URN 的命名来避免冲突。
运行时、浏览器与 WASM 使用
- 可与 Deno、Node、Bun 配合使用;Node 通过兼容层运行。
- 浏览器使用尚未成为一等支持;文中提到 esm.sh 等外部服务,可用于 JSR 包的 HTTP/ESM 导入。
- 计划通过 source-phase imports 提案支持从源导入 WASM。
反响与批评
- 积极反应:更好的 TS 支持、自动文档、来源证明、作为 Microsoft 控制的 npm 的替代方案、开源实现。
- 怀疑声音:增加了另一个注册表并加剧生态碎片化;有人认为这些功能可以通过更好的 npm 侧工具来解决。
- 还有人担心过度依赖 TS、额外的构建“魔法”、semver 行为,以及营销问题(“JSR”这个名字、TS 重点与“JavaScript”品牌之间的关系、类似 AI 的落地页)。