天天看點

React+Typescript調用Terra Station Wallet, 以及React+Typescript內建Rust wasm1、環境介紹:2、建立react項目3、建立rust項目4、安裝react依賴5、報錯更改6、錢包連接配接 (至此可以參照terra官方文檔調用錢包)7、wasm調用

1、環境介紹:

rust 1.61.0

cargo 1.61.0

wasm-pack 0.10.3

node 18.10.0

yarn 1.22.10
           

2、建立react項目

//本項目名為wasmapp-react
//1、建立react項目
npx create-react-app wasmapp-react --template typescript
           

3、建立rust項目

//2、建立rust項目 rust項目名為wasm-hello
cd wasmapp-react
cargo new --lib wasm-hello
           

目前項目目錄結構如下:

(base) ➜  wasmapp-react (master) ✗ tree
.
├── README.md
├── package-lock.json
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.css
│   ├── App.test.tsx
│   ├── App.tsx
│   ├── index.css
│   ├── index.tsx
│   ├── logo.svg
│   ├── react-app-env.d.ts
│   ├── reportWebVitals.ts
│   └── setupTests.ts
├── tsconfig.json
└── wasm-hello
    ├── Cargo.toml
    └── src
        └── lib.rs
           

4、安裝react依賴

//以下按順序執行
yarn

yarn add @terra-money/terra.js
yarn add @terra-money/wallet-provider
           

将terra依賴引入index.tsx,并修改index.tsx内容:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import 'semantic-ui-css'
import {getChainOptions ,WalletProvider} from '@terra-money/wallet-provider'

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
getChainOptions().then(chainOptions => {
  root.render(
    <WalletProvider {...chainOptions}>
      <App />
    </WalletProvider>
  );
})

reportWebVitals();
           

啟動項目:

yarn start
           

上述步驟執行完,浏覽器應該會報如下錯誤:

1、Uncaught ReferenceError: Buffer is not defined

    at ./node_modules/@terra-money/terra.js/dist/core/PublicKey.js (bundle.js:28070:34)

2、Uncaught ReferenceError: stream is not defined

發生報錯後,頁面是無法正常顯示,我們需要做如下工作:

5、報錯更改

出現上述錯誤是因為浏覽器加載不到Buffer,我們是否可以通過yarn add buffer解決呢,并不行。

為解決上述錯誤,我們需要對webpack配置進行改造:

首先我們需要新增一些react依賴包:

yarn add --dev react-app-rewired process crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer next-tick
           

安裝完依賴之後我們需要修改兩個檔案:

(1)package.json

in package.json
//before edit

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },


// after edit

 "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "build:wasm": "cd wasm-hello && wasm-pack build --target web --out-dir pkg",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },
           

(2)tsconfig.json

{
  "compilerOptions": {
    "paths" : {
      "crypto": ["./node_modules/crypto-browserify"],
      "stream": ["./node_modules/stream-browserify"],
      "assert": ["./node_modules/assert"],
      "http": ["./node_modules/stream-http"],
      "https": ["./node_modules/https-browserify"],
      "os": ["./node_modules/os-browserify"]
    },
    "target": "ES2018",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "watch": true,
  },
  "include": [
    "src"
  ]
}
           

做完上述修改工作我們還需建立兩個檔案

(1)項目根目錄建立config-overrides.js

此檔案為了替換webpack的部配置設定置

const webpack = require('webpack');

module.exports = function override(config) {
    const fallback = config.resolve.fallback || {};
    Object.assign(fallback, {
        "crypto": require.resolve("crypto-browserify"),
        "stream": require.resolve("stream-browserify"),
        "assert": require.resolve("assert"),
        "http": require.resolve("stream-http"),
        "https": require.resolve("https-browserify"),
        "os": require.resolve("os-browserify"),
        "url": require.resolve("url")
    })
    config.resolve.fallback = fallback;
    config.plugins = (config.plugins || []).concat([
        new webpack.ProvidePlugin({
            process: 'process/browser',
            Buffer: ['buffer', 'Buffer']
        })
    ])
    config.ignoreWarnings = [/Failed to parse source map/];
    return config;
}
           

(2) 在src目錄下建立polyfills.ts

import { Buffer } from 'buffer';
(window as any).global = window;
global.Buffer = Buffer;
global.process = {
    env: { DEBUG: undefined },
    version: '',
    nextTick: require('next-tick')
} as any;
           

(3)在index.tsx引入polyfills.ts:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import './polyfills';
import reportWebVitals from './reportWebVitals';
import {getChainOptions ,WalletProvider} from '@terra-money/wallet-provider'

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
getChainOptions().then(chainOptions => {
  root.render(
    <WalletProvider {...chainOptions}>
      <App />
    </WalletProvider>
  );
})

reportWebVitals();
           

6、錢包連接配接 (至此可以參照terra官方文檔調用錢包)

7、wasm調用

rust編寫的函數要讓react通路到需要使用rust的wasm-bindgen依賴

隻需執行cargo install wasm-pack即可,wasm-pack在運作時會自動下載下傳wasm-bindgen

我們需要修改Cargo.toml檔案如下:

[package]
name = "wasm-hello"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
wasm-bindgen = "0.2.63"
           

在lib.rs檔案中定義我們的函數:

use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

#[wasm_bindgen]
extern {
    fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(hel:&str) {
    let init = "Hello, wasm-vue".to_string();
    let res =init +  &hel;
    alert(&res);
}
           

至此我們需将rust編譯為wasm形式:

在步驟5中,我們已經在package.json中配置了build:wasm指令,以編譯rust
是以,我們隻需執行:

yarn build:wasm
           

執行完之後, wasm-hello檔案夾中會新增pkg檔案夾

React+Typescript調用Terra Station Wallet, 以及React+Typescript內建Rust wasm1、環境介紹:2、建立react項目3、建立rust項目4、安裝react依賴5、報錯更改6、錢包連接配接 (至此可以參照terra官方文檔調用錢包)7、wasm調用

 最後,我們需要将rust編譯後的内容install到node_modules中:

// 項目根目錄執行
yarn add ./wasm-hello/pkg
           
React+Typescript調用Terra Station Wallet, 以及React+Typescript內建Rust wasm1、環境介紹:2、建立react項目3、建立rust項目4、安裝react依賴5、報錯更改6、錢包連接配接 (至此可以參照terra官方文檔調用錢包)7、wasm調用

至此,我們的錢包調用和wasm內建都完成了,重新啟動項目即可

項目代碼見github:

GitHub - shaozhupeng/wasmapp-react: react+typescript+rust + wasm, terra wallet provider, terra.js