详解TypeScript编译TSX文件的方法
本文深入解析TypeScript中TSX文件的编译机制,重点讲解tsconfig.json中jsx选项的不同模式及其对编译输出的影响。通过Preact和Snabbdom两个虚拟DOM库的实战案例,演示如何配置jsxFactory和jsxImportSource以适配不同的运行时环境,并对比React标准编译路径与自定义JSX工厂函数的差异。
一、简介
由于项目采用 Cycle.js 配合 Vite 和 TSX 技术栈,为了深入理解 TSX 在 TypeScript 配置中的编译行为,本文详细探讨 tsconfig 配置及 TSX 的编译过程。内容涵盖以 Preact 虚拟 DOM 结合 TSX、snabbdom 结合 TSX 等不同配置下的编译输出差异。
除了 TypeScript 原生编译外,还可以利用 Babel 等编译器进行 TSX 处理。
二、配置项目
| 配置选项 | 描述 | 示例配置 |
|---|---|---|
"jsx" | 指定 JSX 的处理方式 | "jsx": "react" |
"jsxFactory" | 指定在 JSX 中使用的工厂函数 | "jsxFactory": "h" |
"jsxFragmentFactory" | 指定在 JSX 中使用的碎片工厂函数 | "jsxFragmentFactory": "Fragment" |
"jsxImportSource" | 指定从哪个模块导入 JSX 相关的符号 | "jsxImportSource": "react" |
"reactNamespace" | 指定全局变量或模块的命名空间,用于 React | "reactNamespace": "myReact" |
"jsxMode" | 指定 JSX 模式,仅在 TypeScript 4.1+ 中可用 | "jsxMode": "react" |
例如:Preact 提供了专用的渲染函数 h 用于组件渲染,这对应着
jsxFactory配置项的设置。
三、配置文件和命令行的优先级问题
- 命令行参数具有更高优先级
- 配置文件优先级较低
例如:jsx 标识符在命令行中使用 --jsx react 会覆盖 jsx: react-jsx 的配置。
四、JSX 标识
1) 没有标识符
若未设置标识符,则不支持编译 TSX/JSX 文件。
2)preserve 标识符
默认情况下,该模式会将 TSX 文件转换为 JSX 文件,其他 JSX 结构保持不变。
3)react/react-native 标识符
默认会使用 React.createElement 来创建元素,输出 js 文件,此时可以与 jsxFactory 工厂函数替换库中的函数。
4)react-jsx/react-jsxdev
该模式会使用相关的 React jsx-runtime 进行编译,同时也支持使用自定义的 jsx-runtime 运行时。
五、PReact 虚拟dom 和 JSX
1) 写法一: 使用 preact 运行时
{
"jsx": "react-jsx",
"jsxImportSource": "preact",
}得到的编译结果是:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("preact/jsx-runtime");
function Card({ title, children }) {
return ((0, jsx_runtime_1.jsxs)("div", { class: "card", children: [(0, jsx_runtime_1.jsx)("h1", { children: title }), children] }));
}使用 preact 的 jsx 运行时。
2) 写法二: 使用 preact 提供的渲染函数 h 进行渲染
{
"jsx": "react",
"jsxFactory": "h",
}得到的编译结果是:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const preact_1 = require("preact");
function Card({ title, children }) {
return ((0, preact_1.h)("div", { class: "card" },
(0, preact_1.h)("h1", null, title),
children));
}
;使用 preact 的渲染函数 h。
六、snabbdom 与 @herp-inc/snabbdom-jsx
1)写法一:使用 jsx
{
"jsx": "react-jsx",
"jsxImportSource": "@herp-inc/snabbdom-jsx",
}编译结果
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("@herp-inc/snabbdom-jsx/jsx-runtime");
// import { jsx } from '@herp-inc/snabbdom-jsx'
const EventComp = () => {
return (0, jsx_runtime_1.jsx)("div", { children: "sdfdsfdd" });
};
exports.default = EventComp;使用 jsx 的运行时
2) 写法: jsx 使用
{
"jsx": "react",
"jsxFactory": "jsx",
"jsxFragmentFactory": "Fragment",
}编译的结果:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const snabbdom_jsx_1 = require("@herp-inc/snabbdom-jsx");
const EventComp = () => {
return (0, snabbdom_jsx_1.jsx)("div", null, "sdfdsfdd");
};
exports.default = EventComp;使用@herp-inc/snabbdom-jsx内部实现的 jsx 函数。
七、snabbdom-jsx
没有运行时:snabbdom-jsx/jsx-runtime 所以不能使用 jsx 运行时编译
1)写法一
{
"jsx": "react",
"jsxFactory": "html",
}组件写法以及编译后的写法
import { html } from 'snabbdom-jsx';
export const vnode = <div>Hello JSX</div>
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.vnode = void 0;
const snabbdom_jsx_1 = require("snabbdom-jsx");
exports.vnode = (0, snabbdom_jsx_1.html)("div", null, "Hello JSX");是使用了 snabbdom-jsx 提供的 html函数,源码如下:
module.exports = {
html: JSX(undefined),
svg: JSX(SVGNS, 'attrs'),
JSX: JSX
};小结
本文旨在讲解 TypeScript 中的编译配置,以及在不同环境下编译不同 JSX/TSX 文件的方法。由于 React 的 JSX 实现了 jsx-runtime,因此基本上存在两套编译路径。若对 TSX 编译机制不了解,本文可作为参考。此外,也可使用 Babel 等其他工具进行编译学习。在 Cycle.js 中使用 snabbdom 作为虚拟 DOM 时,可以使用 TSX 来避免不优雅的虚拟 DOM 写法。
以上就是详解TypeScript编译TSX文件的方法的详细内容,更多关于TypeScript编译TSX文件的资料请关注本站其它相关文章!
JS split切割后出现空字符串怎么过滤
2026-11-05 16:00:30
在 React 或 Vue 项目中封装使用 JS 节流防抖
2026-11-05 15:27:29
JavaScript中怎么将带小数的字符串转为整数?
2026-11-05 14:32:38
怎么用JavaScript策略模式重构电商促销计算逻辑?
2026-11-05 14:01:09
JS使用constructor判断数据类型可靠吗
2026-11-05 13:49:41








