一、项目背景
在 React 面试中,手写 JSX 编译器是高频考点。面试官常常会问:“JSX 到底是怎么变成 JS 的?”“能不能不用 Babel 实现一个简单的 JSX 转换?”
本项目以最小可运行单元,演示了 JSX 到 JS 的转换过程,帮助你彻底搞懂底层原理,轻松应对面试。
二、目录结构与文件说明
compile_jsx/
├── 1.jsx // 简单 JSX 示例
├── 1.js // 1.jsx 编译后的 JS
├── 2.jsx // 复杂 JSX 示例(嵌套、属性)
├── 2.js // 2.jsx 编译后的 JS
├── .babelrc // Babel 配置,启用 JSX 转换
├── package.json // 依赖与脚本
├── pnpm-lock.yaml // pnpm 锁定文件
├── readme.md // 项目说明
三、JSX 到 JS 的转换原理
JSX 其实不是浏览器原生支持的语法,而是 React 社区提出的一种“语法糖”。
它最终会被 Babel 等工具编译为 React.createElement 形式的 JavaScript 代码。
1. JSX 示例
const element = <h1>Hello, world!</h1>;
上述代码用Babel编译后,输出以下代码:
const element = (
<div>
<h1>Title</h1>
<p>内容</p>
<span className="red">红色</span>
</div>
);
2. JS
const element = React.createElement("h1", null, "Hello, world!");
编译输出为:
const element = React.createElement("div", null,
React.createElement("h1", null, "Title"),
React.createElement("p", null, "内容"),
React.createElement("span", { className: "red" }, "红色")
);
可以看到,JSX 语法被 Babel 转换成了嵌套的 React.createElement 调用。
四、Babel 配置详解
项目根目录下的 .babelrc 文件内容如下:
{
"presets": ["@babel/preset-react"]
}
@babel/preset-react负责将 JSX 语法转换为React.createElement形式。- 你也可以自定义 pragma,比如转成
h(),但这里保持 React 默认。
五、如何运行与体验
-
安装依赖(推荐 pnpm,npm/yarn 也可):
pnpm install -
使用 Babel 编译 JSX 文件:
npx babel 1.jsx -o 1.js npx babel 2.jsx -o 2.js -
查看生成的 JS 文件,理解每一步的转换。
-
你也可以在
package.json里配置 script,批量编译:"scripts": { "build": "babel 1.jsx -o 1.js && babel 2.jsx -o 2.js" }然后运行:
pnpm run build
六、面试延伸与思考
-
JSX 为什么不是 JS?
JSX 需要编译,是为了让开发体验更好,但本质上它不是浏览器原生支持的 JS 语法。 -
手写 JSX 编译器的思路?
其实就是把<tag>内容</tag>结构转成createElement(tag, props, ...children)。
可以用正则、AST 工具(如 babel-parser)实现。 -
Babel 的作用?
Babel 作为转译器,能把新语法(如 JSX、ES6+)转成浏览器能识别的老 JS 代码。 -
React.createElement 的参数?
- 第一个参数:标签名或组件
- 第二个参数:属性对象
- 第三个及以后参数:子节点
-
如何自定义 JSX 转换目标?
Babel 支持自定义 pragma,比如转成h(),适用于 Preact、Vue JSX 等场景。
七、总结
- 本项目用最简代码,完整演示了 JSX 到 JS 的转换过程。
- 理解底层原理,有助于面试答题和日常开发调试。
- 推荐大家动手试试,甚至可以尝试自己写一个 mini JSX 转换器!