{"title": "\u5728React App\u91cc\u6267\u884cRust\u7684WASM", "update_time": "2021-08-22 22:56:01", "tags": "rust react", "pid": "353", "icon": "linux.png"}
## 使用Rust构建一个WASM 如果还没安装Rust,请移步 Rust安装教程。下面操作假定已经有Rust开发环境。 新建一个项目 ``` cargo new rust-wasm ``` 修改Cargo.toml ``` [package] name = "rust-wasm" version = "0.1.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2.48" ``` 删掉src/main.rs ``` rm src/main.rs ``` 创建src/lib.rs ``` cat > src/lib.rs <
u32 { match n { 0 => 1, 1 => 1, _ => fibonacci(n - 1) + fibonacci(n - 2), } } EOF ``` 安装wasm-pack (这个工具用于将rust编译为wasm) ``` cargo install wasm-pack ``` 编译rust为wasm (这一步要点时间) ``` wasm-pack build --out-dir /tmp/wasm-build ``` 编译好后, 我们的wasm已经在 /tmp/wasm-build/rust_wasm_bg.wasm ## 使用Create React App创建React应用 ``` npx create-react-app hello-rust-wasm cd hello-rust-wasm npm start ``` ## 将wasm应用到React App 在hello-rust-wasm 项目下,运行如下命令 ``` npm install wasm-loader node-fetch -D ``` 拷贝 rust_wasm_bg.wasm 到public目录 ``` cp /tmp/wasm-build/rust_wasm_bg.wasm public ``` 修改src/App.js ``` import logo from './logo.svg'; import './App.css'; import React from 'react'; import fetch from 'node-fetch'; class App extends React.Component { constructor(props){ super(props); this.state = { fibonacci : null, inputNum: 1, outputNum: 1, } this.reChange = this.reChange.bind(this); } async componentDidMount() { await this.loadWasm(); } getExportFunction = async (url) => { const env = { memoryBase: 0, tableBase: 0, memory: new WebAssembly.Memory({ initial: 256 }), table: new WebAssembly.Table({ initial: 2, element: 'anyfunc' }) }; const instance = await fetch(url).then((response) => { return response.arrayBuffer(); }).then((bytes) => { return WebAssembly.instantiate(bytes, {env: env}) }).then((instance) => { return instance.instance.exports; }); return instance; }; loadWasm = async () => { const wasmUrl = '/rust_wasm_bg.wasm'; const { fibonacci } = await this.getExportFunction(wasmUrl); // 将函数放到state中,便于在render中调用 this.setState({fibonacci: fibonacci,inputNum:1, outputNum: 1}); }; reChange(e){ this.setState( (prevState) => ({ fibonacci : prevState.fibonacci, inputNum: e.target.value, outputNum: prevState.fibonacci(e.target.value), }) ) } render() { const { fibonacci = {} } = this.state; if (typeof(fibonacci)=="function"){ console.log(fibonacci(10)); return (
Ready
{this.state.outputNum}
); } else{ return (
Loading
); } } } export default App ``` ## 参考 * https://zh-hans.reactjs.org/docs/create-a-new-react-app.html * https://www.cnblogs.com/detectiveHLH/p/9881626.html * https://koala42.com/using-webassembly-in-your-reactjs-app/