Skip to main content
Version: 3.x

React TSX 编译器

  • 开始日期:2023-08-14
  • 目标主要版本:1.x
  • 参考问题:
  • 实现 PR:

概括

增加 React TSX 编译器,用于将 TypeScript 编写的 React 无状态组件编译为 C 代码。

基本示例

示例 tsx 文件内容:

import React from "react";
import styles from "./home.module.css";

export default function Home() {
return (
<div className="home">
<text className={styles.text}>Hello, World!</text>
<button className={styles.button}>Ok</button>
</div>
);
}

示例 CSS 文件内容:

:global(.home) {
padding: 20px;
}

.button {
padding: 5px 10px;
text-align: center;
border: 1px solid #eee;
border-radius: 4px;
}

.text {
color: #f00;
font-size: 24px;
}

执行 lcui compile home.tsx 命令后,生成 home.tsx.h 文件:

/** This file is generated from home.tsx */

#include <ui.h>

/** This css code string is compiled from file home.module.css */
static const char *css_str_0 = "\
.home {\
padding: 20px;\
}\
\
._button_1ayu2_9 {\
padding: 5px 10px;\
text-align: center;\
border: 1px solid #eee;\
border-radius: 4px;\
}\
\
._text_1ayu2_23 {\
color: #f00;\
font-size: 24px;\
}\
\
";


static void home_load_template(ui_widget_t *home_parent)
{
ui_widget_t *w[5];

w[0] = ui_create_widget(NULL);
ui_widget_add_class(w[0], "home");
w[1] = ui_create_widget(NULL);
ui_widget_add_class(w[1], "_text_1ayu2_23");
w[2] = ui_create_widget("text");
ui_widget_set_text(w[2], "Hello, World!");
ui_widget_append(w[1], w[2]);
w[3] = ui_create_widget(NULL);
ui_widget_add_class(w[3], "_button_1ayu2_9");
w[4] = ui_create_widget("text");
ui_widget_set_text(w[4], "Ok");
ui_widget_append(w[3], w[4]);
ui_widget_append(w[0], w[1]);
ui_widget_append(w[0], w[3]);
}

static void home_load_resources(void)
{
ui_load_css_string(css_str_0, "home.tsx");
}

home.c 文件中添加 #include "home.tsx.h" 即可使用它。

动机

React 是 Web 前端领域中比较流行的开发技术。对于有 React 开发经验的人,更易于上手 LCUI 的组件开发。对于其他人,多了一种可以尝试的开发方式。

详细设计

基于 typescript 库提供的 transpileModule() 实现对 TypeScript 代码的解析和编译,编译流程大致如下:

  1. 调用 transpileModule() 传入自定义的 transformer 函数,记录所有通过 import 语句引入的 css 文件路径及代码起止位置。
  2. 将 TypeScript 源码中的 css 文件相关的 import 语句替换成 const xxx = {}
  3. 调用 transpileModule() 将 TypeScript 代码编译为 JavaScript 代码。
  4. 将 JavaScript 代码写入到 js 文件中。
  5. 使用 import() 函数加载 js 文件。
  6. 执行 js 文件默认导出的组件函数,得到 JSX 元素树。
  7. 转换 JSX 元素树为 JSON 编译器支持的格式。
  8. 将记录的 css 文件转换为 resource 元素合并到 JSON 数据中。
  9. 调用 JSON 编译器编译 JSON 数据。

缺点

无。

备选方案

无。

采用策略

这是一项新增的功能。