npm 兼容性
使用 npm
和 node_modules
的工具可以通过 JSR 的 npm 兼容性层使用 JSR。此类工具的示例包括 Node.js、Cloudflare Workers、Vite、Esbuild、Webpack 和 Rollup。
如果您使用的是 Deno,您可以 使用
jsr:
导入。
借助此兼容性层,所有 JSR 包都可以使用现有的 npm 兼容包管理器(如npm
、yarn
和pnpm
)进行安装。这使您能够在任何支持使用node_modules
的 npm 包的工具中使用 JSR 包。使用此兼容性层时,您可以像往常一样使用npm install
/ yarn add
/ pnpm install
安装 JSR 包。JSR 包将从 jsr.io 下载并安装到您的node_modules
目录中。
安装和使用 JSR 包
您可以使用jsr
CLI 将 JSR 包添加到您的项目中
npx jsr add @luca/cases
这会将@luca/cases
包添加到您的package.json
文件中,并使用您首选的包管理器将其安装到您的node_modules
目录中。
将根据您的项目中是否存在package.lock
、yarn.lock
或pnpm-lock.yaml
文件自动检测要使用的包管理器。您也可以使用--npm
、--yarn
或--pnpm
标志显式指定要使用的包管理器,这些标志用于jsr add
命令。
您应该检查添加到源代码控制中的
.npmrc
文件。这将使将来对npm install
/yarn
/pnpm install
的调用成功。
然后,您可以从代码中使用 JSR 包
import { camelCase } from "@luca/cases";
注意:由于
npm
和yarn
的限制,它们有时可能会安装 JSR 依赖项的重复副本。这会导致node_modules
目录比必要的大,并且对于某些包,这会导致意外行为。我们建议使用pnpm
以获得最佳体验。
限制
JSR npm 兼容层并非原生 JSR 支持的完美替代品,存在一些限制。
- 您无法使用
jsr:
规范导入 JSR 包。 - 与原生 JSR 导入不同,您不会直接导入 TypeScript 代码。相反,JSR 会将 TypeScript 代码转译为 JavaScript,然后将其安装到您的
node_modules
目录中。这通常意味着您的编辑器体验会受到影响,因为“转到定义”和其他功能将链接到转译后的 JavaScript 代码或生成的.d.ts
文件。 - 安装时间通常会比原生 JSR 支持慢,因为 npm 会下载文件,即使它们在您的项目中未使用。
- 您无法使用 npm 兼容层发布 JSR 包,使用
npm publish
。您只能使用jsr publish
或deno publish
发布 JSR 包。
高级设置
JSR npm 兼容层通过在特殊的 @jsr
npm 范围内提供所有 JSR 包来工作。@jsr
npm 范围不是真正的 npm 范围,您无法向其发布包。您只能使用它从 npm 安装 jsr 包。
@jsr
npm 范围来自 JSR 注册表 https://npm.jsr.io
。这意味着您需要配置您的包管理器以使用此注册表来安装 JSR 包。当使用 jsr
CLI 添加包时,这将自动完成。
除了使用 jsr
CLI 安装 JSR 包之外,您还可以手动配置您的包管理器以支持安装 JSR 包。
为此,创建一个 .npmrc
文件,并在其中添加以下行
@jsr:registry=https://npm.jsr.io
这指示您的包管理器从 JSR 后端而不是 npm 加载 @jsr
范围内的所有包。
您还可以通过在您的主目录中创建一个具有相同内容的 .npmrc
文件,来配置您的包管理器以支持您机器上的所有项目中的 JSR。
然后,您可以像往常一样使用 npm install
/ yarn add
/ pnpm install
手动安装 JSR 包,使用特殊的 @jsr
npm 范围
npm install @jsr/luca__cases@1 # installs the @luca/cases package from JSR
yarn add @jsr/luca__cases@1 # installs the @luca/cases package from JSR
pnpm install @jsr/luca__cases@1 # installs the @luca/cases package from JSR
@jsr/
范围后面的名称是您要安装的 JSR 包的名称。此名称与您使用 jsr:
导入时使用的包名称相同,只是删除了范围前的 @
前缀,并将范围和名称之间的 /
替换为 __
。
例如,jsr:@luca/cases
包可以在 @jsr/luca__cases
中找到。
然后,您可以在代码中使用 @jsr
范围导入 JSR 包。
import { camelCase } from "@jsr/luca__cases";
如果您想在不指定 @jsr/
的情况下导入包,您可以更新 package.json
中的 dependencies
对象。
// package.json
{
"type": "module",
"dependencies": {
- "@jsr/luca__cases": "1"
+ "@luca/cases": "npm:@jsr/luca__cases@1"
}
}
然后,您可以使用在 package.json
中定义的名称导入包。
import { camelCase } from "@luca/cases";
技术细节
@jsr
npm 范围是一个特殊范围,用于将 JSR 包映射到 npm 包,适用于不支持 JSR 的系统。@jsr
npm 范围不是真正的 npm 范围,您无法发布包到它。您只能使用它从 npm 安装 JSR 包。
@jsr
包不会从 https://registry.npmjs.org
的 npm 注册表中提供。相反,它们从 https://npm.jsr.io
的 JSR 注册表中提供。此端点实现 npm 注册表 API。例如,要获取 @jsr/luca__cases
包的元数据,您可以向 https://npm.jsr.io/@jsr/luca__cases
发送 GET
请求。
此端点为 @jsr
包提供与 npm 兼容的 tarball。这些 tarball 由 JSR 生成,包含从包的入口点可访问的所有源代码。此源代码被转译为 JavaScript,并且为所有 TypeScript 文件生成 TypeScript 类型声明 (.d.ts
文件)。tarball 还包含一个 package.json
文件,其中包含原始 jsr.json
/ deno.json
文件中的 exports
字段。
在 npm 注册表端点的包版本清单中,不会宣传已撤回的包版本。即使版本被撤回,已撤回版本的 tarball 仍然可用,这意味着在 lockfile 中引用了已撤回版本的工具仍然可以安装该版本。
即使包版本本身没有改变,为特定包版本宣传的特定 tarball 可能会随着时间的推移而改变。这是因为 JSR 注册表可能会为包版本重新生成与 npm 兼容的 tarball,以解决与 npm 的兼容性问题或改进生成的 tarball 中的转译输出。我们称之为 tarball 的“修订版”。tarball 的修订版不会在 npm 注册表端点中宣传,但它包含在 tarball 本身的 URL 中,并且包含在 tarball 中 package.json
文件的 _jsr_revision
字段中。tarball 的修订版不被视为包版本的一部分,并且不会影响语义版本解析。
但是,tarball URL 是不可变的。引用特定 tarball URL 的工具将始终能够下载该确切的 tarball。当生成 tarball 的新修订版时,旧的 tarball 不会被删除,并且将继续在相同的 URL 上可用。新的 tarball 将在包含新修订版的新的 URL 上可用。
由于 tarball URL 包含在包管理器锁文件中,因此运行 npm i
/ yarn
/ pnpm i
永远不会意外下载 tarball 的新修订版。