在 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-runtime
或 jsx-dev-runtime
。例如,如果 JSX 导入源配置为 react
,则生成的代码将把以下内容添加到生成的代码文件中
import { jsx as _jsx } from "react/jsx-runtime";
Deno 通常依赖于显式说明符,这意味着它在运行时不会尝试任何其他说明符,而只会尝试已生成的说明符。这意味着要成功加载 JSX 运行时,"react/jsx-runtime"
需要解析为一个模块。也就是说,Deno 支持远程模块,大多数 CDN 能够轻松解析说明符。
例如,如果你想从 Preact 的 esm.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
、捆绑或编译。