deno.com
本页内容

JSX

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

默认配置 跳转到标题

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

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

使用 "react" 选项会将 JSX 转换为以下 JavaScript 代码

// input
const jsx = (
  <div className="foo">
    <MyComponent value={2} />
  </div>
);

// output:
const jsx = React.createElement(
  "div",
  { className: "foo" },
  React.createElement(MyComponent, { value: 2 }),
);

JSX 自动运行时 (推荐) 跳转到标题

在 React 17 中,React 团队添加了他们称之为 新的 JSX 转换。这增强了 JSX 转换的 API 并使其现代化,并提供了一种自动添加相关 JSX 导入的机制,这样您就不必自己执行此操作。这是使用 JSX 的推荐方式。

要使用较新的 JSX 运行时转换,请更改 deno.json 中的编译器选项。

deno.json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "react"
  },
  "imports": {
    "react": "npm:react"
  }
}

在幕后,jsxImportSource 设置将始终在导入说明符后附加 /jsx-runtime

// This import will be inserted automatically
import { jsx as _jsx } from "react/jsx-runtime";

使用 "react-jsx" 选项会将 JSX 转换为以下 JavaScript 代码

// input
const jsx = (
  <div className="foo">
    <MyComponent value={2} />
  </div>
);

// output
import { jsx as _jsx } from "react/jsx-runtime";
const jsx = _jsx(
  "div",
  {
    className: "foo",
    children: _jsx(MyComponent, { value: 2 }),
  },
);

如果您想使用 Preact 而不是 React,您可以相应地更新 jsxImportSource 值。

deno.json
  {
    "compilerOptions": {
      "jsx": "react-jsx",
-     "jsxImportSource": "react"
+     "jsxImportSource": "preact"
    },
    "imports": {
-     "react": "npm:react"
+     "preact": "npm:preact"
    }
  }

开发转换 跳转到标题

"jsx" 选项设置为 "react-jsxdev" 而不是 "react-jsx" 将向每个 JSX 节点传递额外的调试信息。附加信息是每个 JSX 节点的调用站点的文件路径、行号和列号。

此信息通常在框架中用于增强开发期间的调试体验。在 React 中,此信息用于增强堆栈跟踪,并显示组件在 React 开发者工具浏览器扩展中实例化的位置。

使用 "react-jsxdev" 选项会将 JSX 转换为以下 JavaScript 代码

// input
const jsx = (
  <div className="foo">
    <MyComponent value={2} />
  </div>
);

// output
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
const _jsxFileName = "file:///input.tsx";
const jsx = _jsxDEV(
  "div",
  {
    className: "foo",
    children: _jsxDEV(
      MyComponent,
      {
        value: 2,
      },
      void 0,
      false,
      {
        fileName: _jsxFileName,
        lineNumber: 3,
        columnNumber: 5,
      },
      this,
    ),
  },
  void 0,
  false,
  {
    fileName: _jsxFileName,
    lineNumber: 1,
    columnNumber: 14,
  },
  this,
);

注意

仅在开发期间使用 "react-jsxdev" 信息,而不要在生产环境中使用。

使用 JSX 导入源 Pragma 跳转到标题

无论您的项目是否配置了 JSX 导入源,或者您是否正在使用默认的“legacy”配置,您都可以将 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>
  );
}

jsxImportSourceTypes 跳转到标题

在某些情况下,库可能不提供类型。要指定类型,您可以使用 @jsxImportSourceTypes pragma

/** @jsxImportSource npm:react@^18.3 */
/** @jsxImportSourceTypes npm:@types/react@^18.3 */

export function Hello() {
  return <div>Hello!</div>;
}

或通过 deno.json 中的 jsxImportSourceTypes 编译器选项指定

deno.json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "npm:react@^18.3",
    "jsxImportSourceTypes": "npm:@types/react@^18.3"
  }
}

JSX 预编译转换 跳转到标题

Deno 附带了一个 新的 JSX 转换,该转换针对服务器端渲染进行了优化。它可以比其他 JSX 转换选项快 7-20 倍。不同之处在于,预编译转换会静态分析您的 JSX,并在可能的情况下存储预编译的 HTML 字符串。这样可以避免大量创建 JSX 对象的时间。

要使用预编译转换,请将 jsx 选项设置为 "precompile"

deno.json
  {
    "compilerOptions": {
+     "jsx": "precompile",
      "jsxImportSource": "preact"
    },
    "imports": {
      "preact": "npm:preact"
    }
  }

要防止代表 HTML 元素的 JSX 节点被预编译,您可以将它们添加到 jsxPrecompileSkipElements 设置中。

deno.json
  {
    "compilerOptions": {
      "jsx": "precompile",
      "jsxImportSource": "preact",
+     "jsxPrecompileSkipElements": ["a", "link"]
    },
    "imports": {
      "preact": "npm:preact"
    }
  }

注意

precompile 转换最适用于 PreactHono。React 不支持它。

使用 "precompile" 选项会将 JSX 转换为以下 JavaScript 代码

// input
const jsx = (
  <div className="foo">
    <MyComponent value={2} />
  </div>
);

// output:
import {
  jsx as _jsx,
  jsxTemplate as _jsxTemplate,
} from "npm:preact/jsx-runtime";
const $$_tpl_1 = [
  '<div class="foo">',
  "</div>",
];
function MyComponent() {
  return null;
}
const jsx = _jsxTemplate(
  $$_tpl_1,
  _jsx(MyComponent, {
    value: 2,
  }),
);

您找到所需的信息了吗?

隐私政策