从零实现 React v18,但 WASM 版 - [1] 项目框架搭建

模仿 big-react,使用 Rust 和 WebAssembly,从 0 到 1 实现从零实现 React v18 的核心功能。深入理解 React 源码的同时,还锻炼了 Rust 的技能,简直赢麻了!

代码地址:github.com/ParadeTo/bi...

本文对应 tag:v1

工具

Rust:一种安全、高效和现代的编程语言(省略一万字)。按照官网所示开发即可。

wasm-pack:构建、测试、和发布 Rust WebAssembly 的一站式工具。

cargo-generate:通过已有的 Git 仓库作为模版,快速创建 Rust 项目。

更多介绍可以参考 Rust 和 WebAssembly 入门教程

其他前端常用的工具自行安装即可,就不赘述了。

项目结构

首先,我们搭建起如下的项目结构:

js 复制代码
.
├── Cargo.toml
├── package.json
├── examples
│   └── hello-world // vite 初始化的 react 项目
├── packages
│   ├── react // 通过 cargo generate --git https://github.com/rustwasm/wasm-pack-template 生成的 WASM 项目
│   ├── react-dom // 通过 cargo generate --git https://github.com/rustwasm/wasm-pack-template 生成的 WASM 项目
│   ├── react-reconciler // cargo new 生成的普通 rust 项目
│   └── shared // cargo new 生成的普通 rust 项目

Cargo.toml 如下所示,类似于前端中常说的 monorepo 架构。

ini 复制代码
[workspace]

members = [
    "packages/react",
    "packages/react-dom",
    "packages/react-reconciler",
    "packages/shared"
]

因为 react 和 react-dom 会导出方法供 JS 侧进行调用,所以需要通过 cargo generate --git https://github.com/rustwasm/wasm-pack-template 创建 WASM 项目,另外两个使用 cargon new 创建普通的 Rust 项目即可。

构建调试环境

我们先删掉 hello-world/src/main.tsx 中的代码,写一个非常简单的例子:

ts 复制代码
import {createRoot} from 'react-dom'

const comp = <div>hello world</div>
console.log(comp)
console.log(createRoot(document.getElementById('root')))

在开发环境运行起来,在浏览器调试窗口中可以看到编译后的代码是这样的:

现在我们的目标是让 hello-world 里面使用的是我们当前正在开发的 React,要让上述代码成功运行,我们需要做以下几步:

  1. 修改 hello-world 项目下的 package.json
json 复制代码
    "react": "file://../../packages/react/pkg/react",
    "react-dom": "file://../../packages/react-dom/pkg/react-dom",
  1. 在根目录下的 package.json 添加打包命令,使用 wasm-pack 把 react 和 react-dom 打包成 WASM:
json 复制代码
  "scripts": {
    "build:react": "wasm-pack build packages/react --out-dir pkg/react --out-name jsx-dev-runtime",
    "build:react-dom": "wasm-pack build packages/react-dom --out-dir pkg/react-dom --out-name index",
    "build": "npm run build:react && npm run build:react-dom"
  },
  1. 分别在 react 和 react-dom 中的 lib.rs 添加如下代码:
rust 复制代码
// react/src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn jsxDEV() -> String {
    "hello world".to_string()
}
rust 复制代码
// react-dom/src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn createRoot(container: &JsValue) -> JsValue {
    JsValue::null()
}

由于 Rust 中的命名风格一般是下划线风格的,所以最好改成这样:

rust 复制代码
// react/src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen(js_name = jsxDev)]
pub fn jsx_dev() -> String {
    "hello world".to_string()
}
rust 复制代码
// react-dom/src/lib.rs
use wasm_bindgen::prelude::*;

#[wasm_bindgen(js_name = createRoot)]
pub fn create_root(container: &JsValue) -> JsValue {
    JsValue::null()
}
  1. 在根目录下运行 npm run build,然后在 hello-world 目录下运行 pnpm installnpm run dev,在浏览器中打开页面,可以看到如下输出:

这说明在 JS 侧成功调用了 WASM 导出的方法,调试环境搭建好了。不过有点麻烦的是,如果修改了代码,需要重新执行步骤 4。

下一篇我们来实现 jsx_dev 的功能,敬请期待。

相关推荐
●VON17 小时前
React Native for OpenHarmony:2048 小游戏的开发与跨平台适配实践
javascript·学习·react native·react.js·von
光影少年18 小时前
react状态管理都有哪些及优缺点和应用场景
前端·react.js·前端框架
冻感糕人~20 小时前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
lbb 小魔仙1 天前
【HarmonyOS实战】React Native 鸿蒙版实战:Calendar 日历组件完全指南
react native·react.js·harmonyos
LYFlied1 天前
从 Vue 到 React,再到 React Native:资深前端开发者的平滑过渡指南
vue.js·react native·react.js
AAA阿giao1 天前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
微小冷1 天前
Rust异步编程详解
开发语言·rust·async·await·异步编程·tokio
鸿乃江边鸟1 天前
Spark Datafusion Comet 向量化Rust Native--CometShuffleExchangeExec怎么控制读写
大数据·rust·spark·native
摘星编程2 天前
React Native鸿蒙版:Image图片占位符
react native·react.js·harmonyos
飞羽殇情2 天前
基于React Native鸿蒙跨平台开发构建完整电商预售系统数据模型,完成参与预售、支付尾款、商品信息展示等
react native·react.js·华为·harmonyos