在 Deno 中配置 JSX
Deno 在 .jsx
文件和 .tsx
文件中都内置支持 JSX。Deno 中的 JSX 对于服务器端渲染或生成供浏览器使用的代码非常有用。
默认配置 跳转到标题
Deno CLI 针对 JSX 有一个默认配置,它与 tsc
的默认配置不同。实际上,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 在哪里找到该模块。导入映射也可以用来使导入源更“干净”。例如,如果您想从 (esm.sh)[https://esm.sh/] 使用 Preact 并包含所有类型信息,您可以设置如下所示的导入映射
{
"imports": {
"preact/jsx-runtime": "https://esm.sh/preact/jsx-runtime?dts",
"preact/jsx-dev-runtime": "https://esm.sh/preact/jsx-dev-runtime?dts"
}
}
然后您可以使用以下 pragma
/** @jsxImportSource preact */
或者您可以在编译器选项中配置它
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}
然后,您需要在命令行中传递 --import-map
选项(以及使用配置文件时的 --config
选项),或者在您的 IDE 中设置 deno.importMap
选项(以及 deno.config
选项)。
jsxImportSourceTypes
跳转到标题
在某些情况下,库可能不提供类型。要指定类型,您可以使用 @jsxImportSourceTypes
pragma
/** @jsxImportSource npm:react@^18.3 */
/** @jsxImportSourceTypes npm:@types/react@^18.3 */
export function Hello() {
return <div>Hello!</div>;
}
或者在 deno.json 中通过 jsxImportSourceTypes
编译器选项指定
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "npm:react@^18.3",
"jsxImportSourceTypes": "npm:@types/react@^18.3"
}
}
当前限制 跳转到标题
JSX 导入源支持目前有两个限制
- 没有导入或导出的 JSX 模块在类型检查时不会被正确转译(参见:microsoft/TypeScript#46723)。在运行时会看到关于
_jsx
未定义的错误。要解决此问题,请在文件中添加export {}
或使用--no-check
标志,这将导致模块被正确地发出。 - 使用
"jsx-reactdev"
编译器选项不支持--no-emit
/捆绑/编译(参见:swc-project/swc#2656)。将发生各种运行时错误,提示无法加载jsx-runtime
模块。要解决此问题,请改用"jsx-react"
编译器选项,或者不要使用--no-emit
、捆绑或编译。