rust-wasm + react 新手入门
本文未经许可,禁止任何形式的转载!!!
发现必究!!!
所有文章第一时间发布在公众号:超级英雄吉姆。
这篇文章花了很多心血。希望能够帮助到大家,同时也希望大家能够点赞、关注,这是我持续写作的最大动力!
概要
为什么需要 Webassembly?
曾经复杂计算的需求,多数聚集在后端,随着的技术和业务的日益发展,在前端也出现了越来越多的频繁复杂计算和高性能的需求。此时通过 js 来和后端交互,反而优秀的 js 变成了应用的瓶颈
在这样的情况下,WebAssembly(WASM)提供了高性能和安全的环境,以接近本机的速度来运行计算。
WASM 是一种编译目标,而不是一种语言,你可以通过各种语言(Rust、Golang、C、C++...)编译得到。Chrome、FireFox、Safari、Edge 中得到了很好的支持。
准备
相关知识:
react
node
npm
wasm-pack
rust
rust-wasm
cargo
cargo-generate
wasm-bindgen
linux
linux常用命令
如果你对
Rust
和
React
没有相关的知识储备,请先参照官方文档。
-
Rust:
https://www.
rust-lang.org/
-
React:
https://
reactjs.org/
环境准备:
注: 教程的环境为 mac 系统。
我们需要
npm
和
cargo
。用来构建 react 应用和 rust-wasm。
如果你对两者没有了解。请先参照官方教程。
- npm: https://www. npmjs.com/get-npm
- cargo: https:// doc.rust-lang.org/cargo /getting-started/installation.html
步骤概览
- 创建 React 应用
- Eject React 应用
-
cargo new
创建 Rust 应用 - 创建 Rust 应用
- 编译 WASM
- 在 React 应用中使用 WASM
-
附加
使用
cargo-generate
创建 Rust-Wasm 应用
创建 React 应用
如果你已经使用 React 脚手架,那么你应该会有
npx
命令,这里创建的 React 应用的方式和
React
官方文档一致。就不赘述。
-
创建目录
mkdir react-wasm
-
进入目录
cd react-wasm
-
创建应用
npx create-react-app react-client
当创建好以后我们得到目录结构如下
➜ react-client git:(master) ls
README.md node_modules package-lock.json package.json public src
- 弹出配置(Ejecting)
参考资料: https:// stackoverflow.com/quest ions/49737652/what-does-eject-do-in-create-react-app
-
运行命令
npm run eject
命令完成后,结构如下:
➜ react-client git:(master) ✗ ls
README.md config node_modules package-lock.json package.json public scripts src
测试一下 React 应用是否正常
-
在
react-client
目录下运行npm start
浏览器中访问
http://localhost:3000/
,看到以下的结果,证明 React 应用正常。
创建 Rust 应用
回到
react-wasm
目录下。
➜ react-wasm ls
react-client
-
我们使用
cargo
来创建一个新的文件夹 -
运行
cargo new wasm
,结果如下
➜ react-wasm ls
react-client wasm
-
进入到
wasm
目录下
➜ wasm git:(master) ✗ ls
Cargo.lock Cargo.toml src target
-
打开
Cargo.toml
[package]
name = "wasm"
version = "0.1.0"
authors = ["jim <303600370@qq.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
- 增加依赖
[package]
name = "wasm"
version = "0.1.0"
authors = ["jim <303600370@qq.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]
path ="src/lib.rs"
[dependencies]
wasm-bindgen ="0.2.34"
-
进入到
src
目录下 将main.rs
重命名或者删除之后创建lib.rs
➜ wasm git:(master) ✗ ls
Cargo.lock Cargo.toml src target
➜ wasm git:(master) ✗ cd src
➜ src git:(master) ✗ ls
main.rs
➜ src git:(master) ✗ mv main.rs lib.rs
➜ src git:(master) ✗ ls
lib.rs
➜ src git:(master) ✗
-
运行
cargo build
看下是否能正常编译
➜ src git:(master) ✗ cargo build
Compiling proc-macro2 v1.0.24
Compiling log v0.4.14
Compiling wasm-bindgen-shared v0.2.71
Compiling syn v1.0.60
Compiling bumpalo v3.6.1
Compiling quote v1.0.9
Compiling wasm-bindgen-backend v0.2.71
Compiling wasm-bindgen-macro-support v0.2.71
Compiling wasm-bindgen-macro v0.2.71
Compiling wasm-bindgen v0.2.71
Compiling wasm v0.1.0 (/Users/jim/dev/tmp/react-wasm/wasm)
Finished dev [unoptimized + debuginfo] target(s) in 11.70s
-
编辑
lib.rs
内容
use::wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
#[wasm_bindgen]
pub fn hello() {
unsafe {
alert("Hello World");
宏
#[wasm_bindgen]
会告诉
wasm-bindgen
帮我们生成一个可以调用的方法
此时,你已经准备好了编译 wasm 文件并在 react 应用中使用
关于
wasm-bindgen
- 将 JS 功能导入到 Rust 中,例如 DOM 操作, 控制台日志记录或性能监控。
- 将 Rust 功能导出到 JS,例如类,函数等
- 使用丰富的类型,例如字符串,数字,类,闭包和对象,而不是简单地使用 u32 浮点数。
- 自动为 JS 使用的 Rust 代码生成 TypeScript 绑定
可以参照官方文档 : https:// rustwasm.github.io/docs /wasm-bindgen/
编译 WASM
我们已经完成了定义 Rust 函数并告诉 wasm-bindgen 编译内容的工作。wasm-pack 帮助我们创建 Javascript 和 Typescript 接口。
-
使用
cargo
安装wasm-pack
-
运行
cargo install wasm-pack
命令
由于本机环境已经安装过,所以得到以下结果
➜ src git:(master) ✗ cargo install wasm-pack
Updating `git://mirrors.ustc.edu.cn/crates.io-index` index
Downloaded wasm-pack v0.9.1 (registry `git://mirrors.ustc.edu.cn/crates.io-index`)
Downloaded 1 crate (422.5 KB) in 3.23s
Ignored package `wasm-pack v0.9.1` is already installed, use --force to override
➜ src git:(master) ✗
同样可以参考官方文档
wasm-pack
:
https://
rustwasm.github.io/wasm
-pack/installer/
-
确保你的
wasm-pack
已经安装完成 -
运行
wasm-pack
命令,得到以下结果
➜ src git:(master) ✗ wasm-pack
wasm-pack 0.9.1
Ashley Williams <ashley666ashley@gmail.com>
✨ pack and publish your wasm!
USAGE:
wasm-pack [FLAGS] [OPTIONS] <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-q, --quiet No output printed to stdout
-V, --version Prints version information
-v, --verbose Log verbosity is based off the number of v used
OPTIONS:
--log-level <log_level> The maximum level of messages that should be logged by wasm-pack. [possible values:
info, warn, error] [default: info]
SUBCOMMANDS:
build ️ build your npm package!
help Prints this message or the help of the given subcommand(s)
login Add an npm registry user account! (aliases: adduser, add-user)
new create a new project with a template
pack create a tar of your npm package but don't publish!
publish pack up your npm package and publish!
test test your wasm!
-
使用
wasm-pack build
命令编译 wasm 文件 -
可以通过
--out-dir
来指定文件输出位置 -
这里我们不指定目录直接运行
wasm-pack build
命令
➜ src git:(master) ✗ wasm-pack build
[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
Compiling proc-macro2 v1.0.24
Compiling unicode-xid v0.2.1
Compiling log v0.4.14
Compiling syn v1.0.60
Compiling wasm-bindgen-shared v0.2.71
Compiling cfg-if v1.0.0
Compiling bumpalo v3.6.1
Compiling lazy_static v1.4.0
Compiling wasm-bindgen v0.2.71
Compiling quote v1.0.9
Compiling wasm-bindgen-backend v0.2.71
Compiling wasm-bindgen-macro-support v0.2.71
Compiling wasm-bindgen-macro v0.2.71
Compiling wasm v0.1.0 (/Users/jim/dev/tmp/react-wasm/wasm)
warning: unnecessary `unsafe` block
--> src/lib.rs:13:5
13 | unsafe {
| ^^^^^^ unnecessary `unsafe` block
= note: `#[warn(unused_unsafe)]` on by default
warning: 1 warning emitted
Finished release [optimized] target(s) in 10.75s
⚠️ [WARN]: origin crate has no README
[INFO]: ⬇️ Installing wasm-bindgen...
[INFO]: Optimizing wasm binaries with `wasm-opt`...
[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
[INFO]: ✨ Done in 6m 50s
[INFO]: Your wasm pkg is ready to publish at /Users/jim/dev/tmp/react-wasm/wasm/pkg.
-
在
wasm
目录下生成了一个pkg
目录
➜ wasm git:(master) ✗ ls
Cargo.lock Cargo.toml pkg src target
➜ wasm git:(master) ✗ cd pkg
➜ pkg git:(master) ✗ ls
package.json wasm.d.ts wasm.js wasm_bg.js wasm_bg.wasm wasm_bg.wasm.d.ts
➜ pkg git:(master) ✗
在
pkg
目录中
*.wasm
就是我们的 WASM 文件。其中还包括了 typescript 的定义
*.d.ts
和 js 文件
*.js
。另外,它还会生成一个
package.json
,接下来,我们将会使用这个文件配合
npm
成为我们 react 的应用依赖。
在 React 应用中使用 WASM
回到我们的 React 应用
-
打开
/react-client/package.json
{
"name": "react-client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@babel/core": "7.12.3",
"@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
"@svgr/webpack": "5.5.0",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.8.1",
"@typescript-eslint/eslint-plugin": "^4.5.0",
"@typescript-eslint/parser": "^4.5.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.0",
"babel-loader": "8.1.0",
"babel-plugin-named-asset-import": "^0.3.7",
"babel-preset-react-app": "^10.0.0",
"bfj": "^7.0.2",
"camelcase": "^6.1.0",
"case-sensitive-paths-webpack-plugin": "2.3.0",
"css-loader": "4.3.0",
"dotenv": "8.2.0",
"dotenv-expand": "5.1.0",
"eslint": "^7.11.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-flowtype": "^5.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-testing-library": "^3.9.2",
"eslint-webpack-plugin": "^2.5.2",
"file-loader": "6.1.1",
"fs-extra": "^9.0.1",
"html-webpack-plugin": "4.5.0",
"identity-obj-proxy": "3.0.0",
"jest": "26.6.0",
"jest-circus": "26.6.0",
"jest-resolve": "26.6.0",
"jest-watch-typeahead": "0.6.1",
"mini-css-extract-plugin": "0.11.3",
"optimize-css-assets-webpack-plugin": "5.0.4",
"pnp-webpack-plugin": "1.6.4",
"postcss-flexbugs-fixes": "4.2.1",
"postcss-loader": "3.0.0",
"postcss-normalize": "8.0.1",
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "5.0.2",
"prompts": "2.4.0",
"react": "^17.0.1",
"react-app-polyfill": "^2.0.0",
"react-dev-utils": "^11.0.3",
"react-dom": "^17.0.1",
"react-refresh": "^0.8.3",
"resolve": "1.18.1",
"resolve-url-loader": "^3.1.2",
"sass-loader": "^10.0.5",
"semver": "7.3.2",
"style-loader": "1.3.0",
"terser-webpack-plugin": "4.2.3",
"ts-pnp": "1.2.0",
"url-loader": "4.1.1",
"web-vitals": "^1.1.0",
"webpack": "4.44.2",
"webpack-dev-server": "3.11.1",
"webpack-manifest-plugin": "2.2.0",
"workbox-webpack-plugin": "5.1.4"
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
"jest": {
"roots": [
"<rootDir>/src"
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts"
"setupFiles": [
"react-app-polyfill/jsdom"
"setupFilesAfterEnv": [
"<rootDir>/src/setupTests.js"
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
"testEnvironment": "jsdom",
"testRunner": "/Users/jim/dev/tmp/react-wasm/react-client/node_modules/jest-circus/runner.js",
"transform": {
"^.+\\.(js|jsx|mjs|cjs|ts|tsx)$": "<rootDir>/config/jest/babelTransform.js",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$",
"^.+\\.module\\.(css|sass|scss)$"
"modulePaths": [],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
"moduleFileExtensions": [
"web.js",
"js",
"web.ts",
"ts",
"web.tsx",
"tsx",
"json",
"web.jsx",
"jsx",
"node"
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
"resetMocks": true
"babel": {
"presets": [
"react-app"
-
在
dependencies
中增加依赖项
"wasm":"file:../wasm/pkg"
结果如下
{
"name": "react-client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@babel/core": "7.12.3",
"@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
"@svgr/webpack": "5.5.0",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.8.1",
"@typescript-eslint/eslint-plugin": "^4.5.0",
"@typescript-eslint/parser": "^4.5.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.0",
"babel-loader": "8.1.0",
"babel-plugin-named-asset-import": "^0.3.7",
"babel-preset-react-app": "^10.0.0",
"bfj": "^7.0.2",
"camelcase": "^6.1.0",
"case-sensitive-paths-webpack-plugin": "2.3.0",
"css-loader": "4.3.0",
"dotenv": "8.2.0",
"dotenv-expand": "5.1.0",
"eslint": "^7.11.0",
"eslint-config-react-app": "^6.0.0",
"eslint-plugin-flowtype": "^5.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-testing-library": "^3.9.2",
"eslint-webpack-plugin": "^2.5.2",
"file-loader": "6.1.1",
"fs-extra": "^9.0.1",
"html-webpack-plugin": "4.5.0",
"identity-obj-proxy": "3.0.0",
"jest": "26.6.0",
"jest-circus": "26.6.0",
"jest-resolve": "26.6.0",
"jest-watch-typeahead": "0.6.1",
"mini-css-extract-plugin": "0.11.3",
"optimize-css-assets-webpack-plugin": "5.0.4",
"pnp-webpack-plugin": "1.6.4",
"postcss-flexbugs-fixes": "4.2.1",
"postcss-loader": "3.0.0",
"postcss-normalize": "8.0.1",
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "5.0.2",
"prompts": "2.4.0",
"react": "^17.0.1",
"react-app-polyfill": "^2.0.0",
"react-dev-utils": "^11.0.3",
"react-dom": "^17.0.1",
"react-refresh": "^0.8.3",
"resolve": "1.18.1",
"resolve-url-loader": "^3.1.2",
"sass-loader": "^10.0.5",
"semver": "7.3.2",
"style-loader": "1.3.0",
"terser-webpack-plugin": "4.2.3",
"ts-pnp": "1.2.0",
"url-loader": "4.1.1",
"web-vitals": "^1.1.0",
"webpack": "4.44.2",
"webpack-dev-server": "3.11.1",
"webpack-manifest-plugin": "2.2.0",
"workbox-webpack-plugin": "5.1.4",
"wasm":"file:../wasm/pkg"
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
"jest": {
"roots": [
"<rootDir>/src"
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!src/**/*.d.ts"
"setupFiles": [
"react-app-polyfill/jsdom"
"setupFilesAfterEnv": [
"<rootDir>/src/setupTests.js"
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
"testEnvironment": "jsdom",
"testRunner": "/Users/jim/dev/tmp/react-wasm/react-client/node_modules/jest-circus/runner.js",
"transform": {
"^.+\\.(js|jsx|mjs|cjs|ts|tsx)$": "<rootDir>/config/jest/babelTransform.js",
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$",
"^.+\\.module\\.(css|sass|scss)$"
"modulePaths": [],
"moduleNameMapper": {
"^react-native$": "react-native-web",
"^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy"
"moduleFileExtensions": [
"web.js",
"js",
"web.ts",
"ts",
"web.tsx",
"tsx",
"json",
"web.jsx",
"jsx",
"node"
"watchPlugins": [
"jest-watch-typeahead/filename",
"jest-watch-typeahead/testname"
"resetMocks": true
"babel": {
"presets": [
"react-app"
-
如果你要更改依赖的名称你需要回到
wasm/pkg
下编辑package.json
{
"name": "wasm",
"collaborators": [
"jim <303600370@qq.com>"
"version": "0.1.0",
"files": [
"wasm_bg.wasm",
"wasm.js",
"wasm.d.ts"
"module": "wasm.js",
"types": "wasm.d.ts",
"sideEffects": false
-
安装
wasm-loader
-
在
react-client
目录下运行npm install --save-dev wasm-loader
,结果如下
➜ react-client git:(master) ✗ npm install --save-dev wasm-loader
npm WARN tsutils@3.20.0 requires a peer of typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta but none is installed. You must install peer dependencies yourself.
+ wasm-loader@1.3.0
added 8 packages from 11 contributors and audited 1962 packages in 12.833s
132 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
-
打开
react-client/config
目录下的webpack.config.js
文件,在rules
中添加以下内容:
//如果存在这行,则不需要
{ parser: { requireEnsure: false } },
test: /\.wasm$/, // only load WASM files (ending in .wasm)
// only files in our src/ folder
include: path.resolve(__dirname, "src"),
use: [{
// load and use the wasm-loader dictionary
loader: require.resolve("wasm-loader"),
options: {}
-
找到
file-loader
,如下:
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
-
在
file-loader
中添加/\.wasm$/
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/,/\.wasm$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
恭喜你到了这一步,接下来我们要修改
App.js
里的内容。
-
打开
/react-client/src
中的App.js
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
Edit <code>src/App.js</code> and save to reload.
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
Learn React
</header>
export default App;
-
修改
App.js
,添加import('wasm').then(module => { console.log(module) })
import logo from './logo.svg';
import './App.css';
function App() {
import('wasm').then(module => {
console.log(module)
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
Edit <code>src/App.js</code> and save to reload.
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
Learn React
</header>
export default App;
-
运行
npm i
保证我们的依赖和配置生效
➜ src git:(master) ✗ npm i
npm WARN tsutils@3.20.0 requires a peer of typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta but none is installed. You must install peer dependencies yourself.
audited 1963 packages in 7.57s
132 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
- 启动 react 应用。打开控制台,看一下输出
可以看到 wasm 已经已经应用成功,还可以看到我们在 rust 应用中定义的 hello 方法
-
编辑
App.js
,调用我们的 wasm 中的 hello 方法
import logo from './logo.svg';
import './App.css';
function App() {
import('wasm').then(({hello}) => {
hello();
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
Edit <code>src/App.js</code> and save to reload.
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
Learn React
</header>
export default App;
*恭喜你~~~~!!!,我们成功的调用了在 rust 应用中定义的 hello 方法,并把它集成在 react 应用中了 *
附加:使用
cargo-generate
创建 Rust-Wasm 应用
如果你阅读到此处还是不能够理解整个流程中我们做了什么的话,建议你重新阅读或者思考一下整个流程。
接下来的内容会需要你对以上内容有一定理解之后阅读起来会比较轻松。接下来的内容,是在上文中的扩展。
-
安装
cargo-generate
cargo install cargo-generate
如果没有 openssl 则使用
cargo install cargo-generate --features vendored-openssl
用例:
cargo generate --git https://github.com/githubusername/mytemplate.git
-
安装
wasm-pack
cargo install wasm-pack
-
安装
wasm-bindgen
cargo install wasm-bindgen-cli --force
- 生成 rust 应用
cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project
cd my-project
得到结果如下
➜ react-wasm cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project
cd my-project
Creating project called `my-project`...
✨ Done! New project created /Users/jim/dev/tmp/react-wasm/my-project
➜ my-project git:(master) ✗
目录结构
➜ my-project git:(master) ✗ ls