使用 React + Rust WASM + CloudFlare 实现一个简单看板

本文最后更新于 2024年4月5日 晚上

Web 前端和 WASM 结合起来, 实现一个看板.

概述

拟实现一个简单的任务看板, 用于管理任务状态.

最初版本需求如下:

  1. 可以展示任务的 ToDo, Doing, Done, Closed 状态.
  2. 可以将任务拖动到不同状态.
  3. 可以新建任务, 修改任务信息, 删除任务.

主要目的:

  1. 调查几种技术集成的方式.
  2. 调查 WASM 的几种部署方式.

调查

工程骨架初始化主要参考: https://www.tkat0.dev/posts/how-to-create-a-react-app-with-rust-and-wasm/

  1. React 看板 UI 实现.
  2. Rust WASM 实现.
  3. 以及如何同 React 前端进行数据交互.

React 前端

前端使用 React + TypeScript, 利用 create-react-app 命令创建项目, 为简化处理, 状态先存放在 Rust WASM 侧, 后续考虑数据库持久化.

  1. 初始化工程: npx create-react-app . --template typescript
  2. 修改了一下代码验证.

Rust 核心

  1. 初始化一个 Rust WASM 项目, 由于项目已创建好目录, 只需要在目录中创建一个 lib 即可, 因此使用到的命令是: cargo init --lib .

  2. 需要将工程设置为 cdylib, 并添加 wasm-bindgen 依赖, 以便将需要导出的函数进行标记, 如下所示:

    在 Cargo.toml 中设置:

    1
    2
    3
    4
    5
    [lib]
    crate-type = ["cdylib"]

    [dependencies]
    wasm-bindgen = "0.2.78"
    1
    2
    3
    4
    5
    6
    use wasm_bindgen::prelude::*;

    #[wasm_bindgen]
    pub fn add(left: usize, right: usize) -> usize {
    left + right
    }

对接

  1. 安装 wasm-pack 以便之后将 rust 代码打包为 wasm: cargo install wasm-pack

  2. 在前端工程中添加一个脚本, 用于打包 wasm: "build:wasm": "cd <rust 工程目录> && wasm-pack build --target web --out-dir <便于前端使用的打包目录>", 比如:

    1
    "build:wasm": "cd ../wasm-rust && wasm-pack build --target web --out-dir pkg",
  3. 前端添加对应依赖项: npm install ../wasm-rust/pkg, 此时 package.json 中会多出来一条依赖记录:

    1
    "wasm-rust": "file:../wasm-rust/pkg",
  4. 在前端调用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import React, { useEffect, useState } from "react";
    import logo from "./logo.svg";
    import "./App.css";
    import init, { add } from "wasm-rust";

    function App() {
    const [ans, setAns] = useState(0);
    useEffect(() => {
    init().then(() => {
    setAns(add(1, 1));
    });
    }, []);

    return (
    <div className="App">
    <header className="App-header">
    <img src={logo} className="App-logo" alt="logo" />
    <p>
    Edit <code>src/App.tsx</code> and save to reload.
    </p>
    <a
    className="App-link"
    href="https://reactjs.org"
    target="_blank"
    rel="noopener noreferrer"
    >
    Learn React with Ease
    </a>
    <p>1 + 1 = {ans}</p>
    </header>
    </div>
    );
    }

    export default App;

实现

实现时, 选型如下:

  1. 前端: React
  2. 底层: Rust WASM
  3. 前端和底层交互.

前端实现: 看板 UI 实现

(参考 fullstack-react-with-typescript 一书)

前端配合 Rust 的 WASM 实现, 实际就是将 UI 放到 React, 前端业务逻辑放到 “客户端 wasm” 中. 暂未进行后端业务开发, 后期考虑放到 CF 的 worker 上.

这里主要看前端的 UI 实现.

UI 提供的动作, 将数据传入底层, 获取到结果后确认展示即可.

前端实现: WASM 底层, 用于处理 side effect

业务逻辑主要是任务和列表的管理.


使用 React + Rust WASM + CloudFlare 实现一个简单看板
https://blog.rayy.top/2024/04/04/rust-react-wasm/
作者
貘鸣
发布于
2024年4月4日
许可协议