跳到主要内容

认识

2023年06月10日
柏拉文
越努力,越幸运

一、认识


Facebook 第一次发布 React 时,他们还引入了一种新的 JS 方言 JSX,将原始 HTML 模板嵌入到 JS 代码中。JSX 代码本身不能被浏览器读取,必须使用Babelwebpack等工具将其转换为传统的JS

React.js 17 之前, 应用程序通过 @babel/preset-react JSX 语法转换为 React.createElementjs 代码,因此需要显式将 React 引入,才能正常调用 createElementReact.js 17 版本之后,官方与 babel 进行了合作,直接通过将 react/jsx-runtimejsx 语法进行了新的转换而不依赖 React.createElement, 称为 Runtime Automatic(自动运行时)。在自动运行时模式下,JSX会被转换成新的入口函数,import {jsx as _jsx} from 'react/jsx-runtime';import {jsxs as _jsxs} from 'react/jsx-runtime';

React 中的 createElement 以及 JSX 都会返回一个 ReactElement 对象, 作为虚拟 DOM 来使用, 用于后续创建 Fiber 对象。

由上所述, React 是纯运行时前端框架, ReactElement 虚拟 DOM 结构已经在运行前编译完成, 在运行中没有机会进行编译优化。

二、编译


2.1 React.js 17.0 之后

React.js 17.0 之后JSX 编译方式为 ['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }], automatic 方式自动引入 jsx 方法, 并且将 JSX 转化为 jsx 函数。

Element

import { jsx as _jsx } from "react/jsx-runtime";

const App = /*#__PURE__*/_jsx("div", {
className: "page-app",
children: "Hello World"
});

Class Component

import { jsx as _jsx } from "react/jsx-runtime";

class App {
render() {
return /*#__PURE__*/_jsx("div", {
className: "page-app",
children: "Hello World"
});
}
}

Function Component

import { jsx as _jsx } from "react/jsx-runtime";

function App() {
return /*#__PURE__*/_jsx("div", {
className: "page-app",
children: "Hello World"
});
}

export default App;

2.1 React.js 17.0 之前

React.js 17.0 之前JSX 编译方式为 ['@babel/plugin-transform-react-jsx', { runtime: 'classic' }], classic 方式只是将将 JSX 转化为 React.createElement 函数。

Element

const App = /*#__PURE__*/React.createElement("div", {
className: "page-app"
}, "Hello World");

Class Component

class App {
render() {
return /*#__PURE__*/React.createElement("div", {
className: "page-app"
}, "Hello World");
}
}

Function Component

function App() {
return /*#__PURE__*/React.createElement("div", {
className: "page-app"
}, "Hello World");
}

三、问题


3.1 Vue Template VS React JSX

React JSX: React 是纯运行时前端框架, 没有机会进行编译优化。React 借助 Babel@babel/plugin-transform-react-jsx 得到包含 jsx 函数的解析结果, jsx 函数用于生成 React.Element

Vue Template: Vue Template 同时支持编译时 + 运行时, 在模版编译的时候可以进行非常好的性能优化, 比如: 动态标记静态节点提升等。 Vue Template 是通过 Vue 自身实现的编译器解析, 最终生成 render 函数, render 函数内部通过 h 函数生成 VNode 虚拟节点。

参考资料


卡颂-React技术揭秘

全栈潇晨