在Mini-React中实现JSX支持:从环境搭建到组件化实践
一、配置JSX开发环境
1. 初始化Vite项目 通过以下命令快速搭建支持JSX的现代前端开发环境:
pnpm create vite
# 项目名:vite-runner
# 框架选择:Vanilla(纯JS)
# 语言选择:JavaScript
这一步生成的基础项目已内置JSX编译能力,无需额外配置。
2. 迁移核心代码 将原有Mini-React代码整合到新项目中:
-
文件结构调整
- 将原
App.js重命名为App.jsx - 复制
core文件夹(包含自定义的React.js核心逻辑) - 更新
main.js入口文件
- 将原
-
修改HTML入口
<!-- index.html --> <div id="root"></div> <script type="module" src="/main.js"></script>确保入口文件路径与项目结构匹配。
3. 验证JSX转换 运行以下命令启动开发服务器:
pnpm install && pnpm dev
观察控制台输出,可以看到:
- JSX语法已被正确转换为
React.createElement调用 - 自定义的
createTextNode方法被触发
二、代码改造与效果验证
1. 改造App组件 将原有元素创建方式改为JSX语法:
// App.jsx
import React from './core/React.js';
// 写法1:通过函数返回JSX
function AppOne() {
return <div id="xxx">aaa-bbbb</div>
}
// 写法2:直接声明JSX常量
const App = <div>aaa-bbbb</div>
console.log("AppOne:", AppOne); // 观察函数组件形态
console.log("App:", App); // 查看转换后的对象结构
export default App;
通过控制台输出可见,两种写法最终都会转换为包含type和props的虚拟DOM对象。
2. React核心逻辑 在core/React.js中实现的简易渲染逻辑:
function createTextNode(text) {
return {
type: "TEXT_ELEMENT",
props: {
nodeValue: text,
children: []
}
}
}
function createElement(type, props, ...children) {
return {
type,
props: {
...props,
children: children.map(child => {return typeof child === "string"? createTextNode(child) : child})
}
}
}
function render(el, container) {
// 1. 判断元素类型是文本还是其他类型, 如果是文本类型则创建文本节点,否则创建元素节点
const dom = el.type === "TEXT_ELEMENT" ? document.createTextNode("") : document.createElement(el.type);
// 2.设置元素的属性值为 el.props 中的属性
Object.keys(el.props).forEach((key) => {
if (key !== "children") {
dom[key] = el.props[key];
}
});
// 递归的处理子元素
const children = el.props.children
children.forEach((child) => {
render(child, dom);
});
// 3. 将创建的元素节点添加到指定的容器中
container.appendChild(dom);
}
const React = {
render,
createElement,
}
export default React
这段代码实现了JSX到虚拟DOM的转换基础能力。
三、当前遗留问题
组件化支持限制
// 期望的组件化写法(暂不可用)
ReactDOM.createRoot(document.querySelector("#root")).render(<App/>)
原因分析: 当前React.js未实现函数组件处理逻辑,无法解析<App/>形式的组件调用。
现象说明:
- 直接使用
<App/>会导致渲染异常 - 必须导出具体的JSX元素(如
export default <div>...</div>)
四、总结
本文记录了为自研Mini-React框架添加JSX支持的完整过程:通过Vite搭建开发环境,验证JSX编译机制,改造现有组件代码,并分析当前组件化支持的局限。核心收获包括:1)理解JSX本质是React.createElement的语法糖;2)掌握虚拟DOM对象的结构特性;3)明确函数组件支持需要扩展渲染逻辑。目前暂不支持<Component/>语法的问题为后续学习指明了方向,为深入理解React组件化原理奠定了基础。