在本页

在 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-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 在哪里找到该模块。导入映射也可以用来使导入源更“干净”。例如,如果您想从 (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、捆绑或编译。