跳至主要内容

在 Deno 中配置 JSX

Deno 在 .jsx 文件和 .tsx 文件中都内置支持 JSX。Deno 中的 JSX 可以方便地用于服务器端渲染或生成供浏览器使用的代码。

默认配置

Deno CLI 具有与 tsc 默认值不同的 JSX 默认配置。实际上,Deno 默认使用以下 TypeScript 编译器 选项

{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "React.createElement",
"jsxFragmentFactory": "React.Fragment"
}
}

JSX 导入源

在 React 17 中,React 团队添加了他们称为 新的 JSX 转换 的内容。这增强并现代化了 JSX 转换的 API,并提供了一种机制,可以自动将 JSX 库导入模块,而不是必须显式导入它或将其作为全局范围的一部分。通常,这使得在应用程序中使用 JSX 变得更加容易。

从 Deno 1.16 版本开始,添加了对这些转换的初步支持。Deno 支持 JSX 导入源 pragma,以及在 配置文件 中配置 JSX 导入源。

JSX 运行时

使用自动转换时,Deno 会尝试导入一个 JSX 运行时模块,该模块应符合新的 JSX API,并位于 jsx-runtimejsx-dev-runtime。例如,如果 JSX 导入源配置为 react,则生成的代码将把以下内容添加到生成的代码文件中

import { jsx as _jsx } from "react/jsx-runtime";

Deno 通常依赖于显式说明符,这意味着它在运行时不会尝试任何其他说明符,而只会尝试已生成的说明符。这意味着要成功加载 JSX 运行时,"react/jsx-runtime" 需要解析为一个模块。也就是说,Deno 支持远程模块,大多数 CDN 能够轻松解析说明符。

例如,如果你想从 Preactesm.sh CDN 中使用 Preact,你可以使用 https://esm.sh/preact 作为 JSX 导入源,esm.sh 将解析 https://esm.sh/preact/jsx-runtime 作为模块,包括在响应中提供一个标头,告诉 Deno 在哪里可以找到 Preact 的类型定义。

使用 JSX 导入源 pragma

无论你是否为项目配置了 JSX 导入源,或者你是否使用默认的“传统”配置,你都可以将 JSX 导入源 pragma 添加到 .jsx.tsx 模块中,Deno 将尊重它。

@jsxImportSource pragma 必须位于模块的开头注释中。例如,要从 esm.sh 中使用 Preact,你可以执行以下操作

/** @jsxImportSource https://esm.sh/preact */

export function App() {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
}

在配置文件中使用 JSX 导入源

如果您想为整个项目配置 JSX 导入源,以便您无需在每个模块中插入 pragma,您可以使用 配置文件 中的 "compilerOptions" 来指定它。例如,如果您使用 esm.sh 中的 Preact 作为您的 JSX 库,您将在配置文件中配置以下内容

{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "https://esm.sh/preact"
}
}

使用导入映射

在导入源加上 /jsx-runtime/jsx-dev-runtime 无法解析到正确模块的情况下,可以使用导入映射来指示 Deno 在哪里找到模块。导入映射也可以用于使导入源更“干净”。例如,如果您想从 skypack.dev 使用 Preact,并让 skypack.dev 包含所有类型信息,您可以这样设置导入映射

{
"imports": {
"preact/jsx-runtime": "https://cdn.skypack.dev/preact/jsx-runtime?dts",
"preact/jsx-dev-runtime": "https://cdn.skypack.dev/preact/jsx-dev-runtime?dts"
}
}

然后,您可以使用以下 pragma

/** @jsxImportSource preact */

或者您可以在编译器选项中配置它

{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}

然后,您需要在命令行中传递 --import-map 选项(以及使用配置文件时的 --config 选项),或在您的 IDE 中设置 deno.importMap 选项(以及 deno.config 选项)。

当前限制

JSX 导入源支持目前有两个限制

  • 没有导入或导出的 JSX 模块在类型检查时不会被正确转译(参见:microsoft/TypeScript#46723)。在运行时会看到有关 _jsx 未定义的错误。要解决此问题,请向文件添加 export {} 或使用 --no-check 标志,这将导致模块被正确发出。
  • 使用 "jsx-reactdev" 编译器选项不支持 --no-emit/捆绑/编译(参见:swc-project/swc#2656)。将发生各种运行时错误,提示无法加载 jsx-runtime 模块。要解决此问题,请改用 "jsx-react" 编译器选项,或不要使用 --no-emit、捆绑或编译。