跳到主要内容
Deno 2.4 发布,带来 deno bundle、字节/文本导入、OTel 稳定版等更多功能
了解更多
The JSR logo on an abstract square background

介绍 JSR - JavaScript 注册表

JSR 简介——极简版

请参阅下文关于我们如何以及为何构建 JSR 的长篇版本

JSR - JavaScript 注册表现已进入公开测试版 - 立即注册!JSR 针对 TypeScript 进行了优化,并且仅支持 ES 模块。它适用于 Deno 和基于 npm 的项目(Node、Bun、Cloudflare Workers 等),并且是免费和开源的。

您可以像这样安装包

# deno
deno add @luca/flag

# npm (and npm-like systems)
npx jsr add @luca/flag

您可以像导入任何其他 ES 模块一样导入包

import { printProgress } from "@luca/flag";

printProgress();

可以从命令行轻松发布您自己的 TypeScript 和 JavaScript 模块

# with deno installed (https://docs.deno.org.cn/runtime/manual)
deno publish

# with npm-like systems
npx jsr publish

模块以 TypeScript 源代码的形式发布到 JSR。API 文档生成、类 Node 环境的类型声明以及转译都由 JSR 处理。模块作者只需专注于编写 TypeScript 即可。

继续阅读,了解更多关于我们如何以及为何构建 JSR、如何立即使用它以及如何参与该项目的信息!

JSR 简介——稍长版本

JavaScript 已成为全球默认的编程语言。无论是运行在浏览器、移动设备、机器人还是服务器上,您都可以使用 JavaScript 编写几乎任何程序。

Node 在过去 15 年中是这一转变的重要组成部分,但在谈论 Node 的成功时,不能不提 npm 同样令人难以置信的成功。拥有超过 250 万个包,仅在过去 30 天内就约有 2500 亿次下载,它无疑是世界上最成功的包注册表。

如果不是 JavaScript 社区共同构建的这个令人难以置信的生态系统,JavaScript 可能不会拥有今天的地位。这应该成为 npm 上每个模块作者的骄傲源泉。

从 2009 年到 2024 年

自 npm 初次发布以来,JavaScript 的世界发生了许多变化。

  • ECMAScript 模块已作为编写可重用 JavaScript 代码的 Web 标准而出现,取代了 CommonJS。
  • TypeScript 已然兴起,它不仅是一种带有编译时类型检查的 JavaScript 编写方式,更是 TC39 最新 JavaScript 语言特性的试验平台。
  • Node 不再是浏览器之外唯一相关的 JavaScript 运行时。像 Denoworkerd (Cloudflare Workers)Bun 以及更多即将推出的运行时,正在开发体验 (DX) 上进行创新,更紧密地遵循 Web 标准,和/或在边缘服务器上进行设计权衡以实现快速启动。

尽管 npm 在当今的 Web 开发中仍是基础组件,但它并非为这些新现实而设计。我们认为,现在是时候重新构想 2024 年的包注册表应如何运作了。

  • 它应该将 ESM 作为 JavaScript 模块的 Web 标准
  • 它应该从第一性原理为 TypeScript 而设计
  • 它应该简单、快速,并提供卓越的开发者体验
  • 它应该免费开源,并且在任何支持 JavaScript 的地方都能工作
  • 它应该基于 npm 的成功,而不是分叉它

为了实现这些设计目标,我们非常高兴能分享 JSR - JavaScript 注册表。从今天起,它已免费开放进行公开测试。我们希望您能注册并尝试一下!

从 JSR 使用模块

JSR 主页上,您可以按名称或包描述搜索模块。下面,我们搜索 HTTP 服务器包,找到了 oak,它是来自 deno.land/x 的更受欢迎的 HTTP 中间件框架之一,并且已发布到 JSR 上。

search results for http server
按名称或描述搜索包

请注意,每个包都有一个质量分数。该分数由越来越多的因素决定,例如文档的完整性、用于快速类型检查的最佳类型声明以及与多个运行时的兼容性。

oak quality score
影响质量分数的一些因素

找到合适的模块后,安装和使用说明可在模块自动生成的 API 参考文档的每个页面的顶部找到。

oak usage instructions
使用 npm 安装和使用 oak 的说明

让我们在 Node.js 项目中使用 npm 来使用 oak。在您的终端中,初始化一个新的 Node 项目,并使用以下命令安装 oak

npm init --yes
npx jsr i @oak/oak

在同一个目录下,创建一个名为 index.mjs 的文件,并添加以下使用您最近安装的 oak 模块的代码

import { Application, Router } from "@oak/oak";

const router = new Router();
router.get("/", (ctx) => {
  ctx.response.body = `<!DOCTYPE html>
    <html>
      <head><title>Hello oak!</title><head>
      <body>
        <h1>Hello oak!</h1>
      </body>
    </html>
  `;
});

const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());

app.listen({ port: 8080 });

您可以使用 node index.mjs 运行此应用程序,然后访问您的“hello, world” oak 应用程序,地址是 https://:8080

发布到 JSR

作为包的创建者,JSR 让您的工作变得轻松许多。您可以用 TypeScript 编写您的包,并将 TypeScript 源代码直接发布到 JSR,无需构建步骤。

为了了解其工作原理(并查看 JSR 在幕后为您做了多少工作),让我们创建并发布一个名为 yassify 的 TypeScript 模块,它将用一些表情符号💅✨👸来美化一段文本字符串。然后,我们将在一个 Astro 项目中使用此模块的 TypeScript 接口,并使用 Node 运行该项目。

由于 Deno 原生支持 TypeScript,因此使用 Deno 构建此模块将是最快的。但是,您可以使用任何您喜欢的运行时来编写 TypeScript。

构建 yassify

在终端中,创建一个名为 yassify 的新文件夹,并在其中创建三个文件

  • jsr.json - 您的包的元数据文件
  • mod.ts - 我们模块的实现(此文件可以任意命名)
  • README.md - 一个 Markdown 文件,将作为您模块在 jsr.io 上的概述

jsr.json 中,包含以下关于您的包的元数据

{
  "name": "@kwhinnery/yassify",
  "version": "1.0.0",
  "exports": "./mod.ts"
}

此元数据包括

  • name 属性,它结合了您包的作用域包名
  • 您包的 version - JSR 包使用语义版本控制进行安装和去重
  • exports 字段,它指定您的包中的哪些模块可供使用者使用。

README.md 中,包含一些关于您包的高级使用说明和示例。目前,使用以下内容应该就足够了

# yassify

Use `yassify` to apply advanced beauty filters to any string of text.

## License

MIT

mod.ts 中,包含 yassify 函数的实现

/**
 * Yassify a string of text by appending emoji
 *
 * @param str The string of text to yassify.
 * @returns a string of text with emoji appended
 */
export function yassify(str: string): string {
  return `${str} 💅✨👑`;
}

创建完这三个文件后,您可以使用以下命令从命令行发布您的模块(如果您使用基于 Node 的环境,则使用 npx jsr publish

deno publish

如果这是您第一次发布此模块,您可能会被提示为其创建作用域和包名。

create scope and package on jsr
一个用于创建您的作用域和包的 UI 将从 CLI 在浏览器中打开

点击“创建”按钮将提示最终授权检查

authorize package creation
授权 CLI 为您创建包

稍等片刻,您的包应该就发布到 JSR 了!

kevin@kevin-deno yassify % deno publish
Check file:///Users/kevin/dev/kwhinnery/yassify/mod.ts
Checking for slow types in the public API...
Check file:///Users/kevin/dev/kwhinnery/yassify/mod.ts
'@kwhinnery/yassify' doesn't exist yet. Visit xxx to create the package
Waiting...
Package @kwhinnery/yassify created
Visit https://jsr.deno.org.cn/auth?code=x to authorize publishing of @kwhinnery/yassify
Waiting...
Authorization successful. Authenticated as Kevin Whinnery
Publishing @kwhinnery/yassify@1.0.0 ...
Successfully published @kwhinnery/yassify@1.0.0
Visit https://jsr.deno.org.cn/@kwhinnery/yassify@1.0.0 for details

如果您访问您的包页面,如 CLI 输出的最后一行所示,您会注意到您创建的 README 文件正在作为您包的主页。您还会注意到您的包的 TypeScript API 文档已自动生成。

package home page
yassify 包在 JSR 上的新家

对于您的包导出的函数和符号,文档是从您的源代码和注释中生成的

package docs
我们包的自动生成 API 文档

您还可以在“设置”选项卡下帮助潜在用户了解哪些运行时支持您的模块。您可能还希望在此处配置模块的描述,该描述将显示在搜索结果中。

package settings
配置支持的运行时和包描述

花时间进行这些更新也将提高您包的整体质量分数。yassify 可能功能不多,但它的文档很完善!

package score
使用支持的运行时和描述来美化 yassify

作为包发布者,目前我们只需完成这些——现在让我们看看作为使用者使用我们包的体验如何。

在 Astro 项目中使用您的新模块

现在是时候使用 Astro 构建一个 Web 应用程序了。要创建一个使用 Node 的 Astro 项目,请执行以下命令

npm create astro@latest

接受所有默认选项,包括使用 TypeScript 进行开发的选项。您还可以允许 Astro 安装其所有 npm 依赖。

创建 Astro 项目后,您可以使用以下命令安装您刚创建的 yassify 模块(根据需要替换为您自己的作用域名称)

npx jsr add @kwhinnery/yassify

安装完我们的包后,在您喜欢的编辑器中打开您的 Astro 项目。如果您使用 Visual Studio Code,您会获得一些不错的特性,我们将在后续指出。

在默认的 Astro 示例代码中,打开 src/components/Card.astro。Astro 组件可以在文件的组件脚本部分使用 TypeScript 代码。在文件顶部,添加一个 yassify 导入,如下所示

import { yassify } from "@kwhinnery/yassify";

如果您正在使用 VS Code,将鼠标悬停在 yassify 导入上——请注意,编辑器中已经提供了内联文档!

inline docs
编辑器中的内联文档,免费提供!

这是因为 JSR 已自动转译您模块中的 TypeScript 代码,并包含了 .d.ts 文件,这些文件为您的编辑器提供了关于模块如何工作的提示。命令点击 yassify 函数,您将看到 Astro 项目的 node_modules 文件夹中的 .d.ts 文件

generated .d.ts file
JSR 为您生成并包含在您的包中的 .d.ts 文件。您的 TypeScript 源代码也被转译为适用于 Node 的 JavaScript。

最后,您可以在 Astro 项目中实际使用 yassify 函数了!在 Card.astro 文件中,按照所示美化组件的 title 属性

<li class="link-card">
  <a href="{href}">
    <h2>
      {yassify(title)}
      <span>&rarr;</span>
    </h2>
    <p>
      {body}
    </p>
  </a>
</li>

如果您尚未启动,现在应该使用以下命令启动本地 Astro 开发服务器

npm start

访问 https://:4321 应该会显示一个新的 Astro 占位符页面,其中所有卡片标题都已适当转换。太棒了!

astro demo page
Astro 已正式被“美化”

从 GitHub 发布

虽然从命令行发布对于尝试新事物来说很好,但您可能希望从 CI 发布您的包。在 JSR 上设置此功能最简单的方法是链接 GitHub 仓库。在 JSR 包的“设置”界面中,配置存储您包源代码的 GitHub 用户名和仓库名。如果您是 Git 和 GitHub 的新手,请在此处了解如何设置 GitHub 仓库

package settings page
为您的包链接一个 GitHub 仓库

链接您的仓库后,将以下配置添加到 .github/workflows/publish.yml 文件中

name: Publish

on:
  push:
    branches:
      - main

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write # The OIDC ID token is used for authentication with JSR.
    steps:
      - uses: actions/checkout@v4
      - run: npx jsr publish

将此文件推送到您的 GitHub 仓库后,对 main 分支的后续提交(当它们包含新版本时)将自动发布到 JSR。

successful GH actions run
一次成功的 GitHub Actions 发布运行

以这种方式发布也让您的用户放心,他们项目中包含的工件确实是从 CI 上传的,并且提供了可供查看的来源透明日志

provenance stamp
一个来源印章,表明上次上传的构建来自 GitHub Actions

帮助我们提升 JavaScript 生态系统

尽管 Deno 团队在 JSR 上投入了大量工作,但我们希望 JSR 能成为一项公共事业,造福整个 JavaScript 生态系统。这就是我们将 JSR 在 MIT 许可证下免费开源的原因。我们已将 JSR 设计得成本低廉且相对容易托管,供任何决定托管它的人使用。

我们还希望将 JSR 作为一个社区空间进行维护。我们仍在努力确定如何管理该项目的具体细节,但作为第一步,我们希望邀请社区版主协助 Deno 团队分配受保护的作用域、处理争议,以及全面指导 JSR 的日常事务。如果您有兴趣成为 JSR 社区版主,请在此处告知我们

我们也需要您的反馈——虽然我们相信 JSR 是非常稳定的软件,但仍有很多工作要做,我们期望在未来几周和几个月内从社区中学到很多东西。

  • 如果您发现 JSR 的问题,请将其报告为GitHub issue
  • 如果您对 JSR 有反馈或希望获得社区帮助,请在 Discord 上的 #jsr#jsr-feedback 频道加入我们。

最后,请在 X/Twitter 上关注 @jsr_io,获取 JSR 团队的新闻和更新。

JavaScript 和 Web 平台很可能在未来几年内仍然是主导的编程环境。我们希望 JSR 能够推动 JavaScript 社区未来 15 年的创新,并帮助 TypeScript 和 JavaScript 开发者无论代码在哪里运行都能更高效。