如何在React專案中直接使用WebAssembly
阿新 • • 發佈:2018-11-02
前言
自從入坑WebAssembly以來,躺了很多坑,也瀏覽了很多資料,都沒有看到很多能夠直接在前端專案中使用WebAssembly的例子。即使有,我自己按照介紹的步驟一步一步來, 也會報各種錯誤,官方的文件也寫的比較模糊。於是,就決定自己擼一個,讓React專案能夠直接的藉助Webpack,在程式碼中引入已經編譯好的C++模組。
寫一個C語言模組
int add(int a, int b) {
return a + b;
}
複製程式碼
使用emscripten對C模組進行編譯
執行以下程式碼對上面的add.c
檔案進行編譯。
emcc add.c -Os -s WASM=1 -s SIDE_MODULE=1 -o add.wasm
複製程式碼
-Os
程式碼我的模組需要優化,-s WASM=1
代表我需要Wasm的第一個版本,-s SIDE_MODULE=1
代表我不需要多餘的程式碼,就只要這一個模組。-o add.wasm
表示我的輸出檔案為add.wasm
。然後就可以看到在與add.c
同級的目錄下生成了add.wasm
。然後把add.wasm
放到public
目錄下。
新建一個react專案
npx create-react-app my-project
cd my-project
yarn install
yarn start
複製程式碼
執行完上述的命令,一個簡單的react專案就在你本地的3000埠啟動了。
獲取webpack控制權
然後再執行以下命令。
yarn run eject
複製程式碼
執行之後就可以看到webpack的配置檔案了。
安裝loader和fetch
yarn add wasm-loader && yarn add node-fetch
複製程式碼
更新webpack配置檔案
找到webpack配置檔案,在相應的位置新增如下配置。
{
test: /\.wasm$/,
type: 'javascript/auto',
loaders: ['wasm-loader']
}
複製程式碼
修改App.js檔案
修改App.js。將其替換為如下程式碼。
import React, {Component} from 'react';
import logo from './logo.svg';
import fetch from 'node-fetch';
import './App.css';
class App extends Component {
componentDidMount() {
this.doSomething();
}
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;
};
doSomething = async () => {
const wasmUrl = 'http://localhost:3000/add.wasm';
const { add } = await this.getExportFunction(wasmUrl);
console.log(add(200,2034));
};
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo"/>
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
}
export default App;
複製程式碼
可以看到App類中有個函式叫getExportFunction
,這個函式接受一個url
引數,這個url是遠端wasm檔案的地址。然後動態的根據傳入url,解析其中的編譯好的function
。
執行
執行以下命令啟動專案。
yarn start
複製程式碼
然後就可以在控制檯中看到輸出的49,是直接呼叫的我們用C語言寫的add函式。
舉個例子
完整的專案程式碼在這裡,歡迎Star。