前言

自从入坑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。

如何在React项目中直接使用WebAssembly的更多相关文章

  1. 如何在VUE项目中添加ESLint

    如何在VUE项目中添加ESLint 1. 首先在项目的根目录下 新建 .eslintrc.js文件,其配置规则可以如下:(自己小整理了一份),所有的代码如下: // https://eslint.or ...

  2. react项目中实现搜索关键字呈现高亮状态(一)

    最近有个需求,在一个react项目中,实现搜索关键字呈现高亮状态.这个在普通的html文件中还好操作些,在react项目中有点懵逼了,因为react项目中很少操作dom,有点无从下手.但最后还是实现了 ...

  3. [Laravel-Swagger]如何在 Laravel 项目中使用 Swagger

    如何在 Laravel 项目中使用 Swagger http://swagger.io/getting-started/ 安装依赖 swagger-php composer require zirco ...

  4. 如何在cocos2d项目中enable ARC

    如何在cocos2d项目中enable ARC 基本思想就是不支持ARC的代码用和支持ARC的分开,通过xcode中设置编译选项,让支持和不支持ARC的代码共存. cocos2d是ios app开发中 ...

  5. 如何在NodeJS项目中优雅的使用ES6

    如何在NodeJS项目中优雅的使用ES6 NodeJs最近的版本都开始支持ES6(ES2015)的新特性了,设置已经支持了async/await这样的更高级的特性.只是在使用的时候需要在node后面加 ...

  6. 如何在非 React 项目中使用 Redux

    本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...

  7. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...

  8. react项目中实现元素的拖动和缩放实例

    在react项目中实现此功能可借助 react-rnd 库,文档地址:https://github.com/bokuweb/react-rnd#Screenshot .下面是实例运用: import ...

  9. React项目中实现右键自定义菜单

    最近在react项目中需要实现一个,右键自定义菜单功能.找了找发现纯react项目里没有什么工具可以实现这样的功能,所以在网上搜了搜相关资料.下面我会附上完整的组件代码. (注:以下代码非本人原创,具 ...

随机推荐

  1. vue中 v-show和v-if的区别?

    v-show的操作元素的属性是display v-if的操作元素的移除和新建 还有一个就是权限的时候,v-show普通用户能看到,用v-if的时候普通用户看不到.

  2. 洛谷.5300.[GXOI/GZOI2019]与或和(单调栈)

    LOJ BZOJ 洛谷 想了一个奇葩的单调栈,算的时候要在中间取\(\min\),感觉不靠谱不写了=-= 调了十分钟发现输出没取模=v= BZOJ好逗逼啊 题面连pdf都不挂了 哈哈哈哈 枚举每一位. ...

  3. go 结构体

    结构体声明 type Employee struct { ID int Name string Address string DoB time.Time Position string Salary ...

  4. maven build时报错Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test

    [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ ...

  5. Cordova打包vue项目生成Apk (解决cordova build android抛出的zip问题)

    最近对vue前端框架情有独钟.但研究了一下怎么把vue项目打包成android apk来玩玩. 首先讲一下创建vue2.x项目.其实在之前的文章中都有写过,有兴趣的同学可以去看看.http://www ...

  6. Centos服务器上NFS灾备环境及KVM的搭建及使用

    1.概述 由于在单台服务器上搭建灾备环境需要KVM和NFS的支持,下面先列出KVM的搭建流程,再列出使用NFS实现单台服务器灾备的流程. A.搭建KVM环境 1>.主机环境准备 Linux Sy ...

  7. [Educational Round 10][Codeforces 652F. Ants on a Circle]

    题目连接:652F - Ants on a Circle 题目大意:\(n\)个蚂蚁在一个大小为\(m\)的圆上,每个蚂蚁有他的初始位置及初始面向,每个单位时间蚂蚁会朝着当前面向移动一个单位长度,在遇 ...

  8. 神经网络_线性神经网络 2 (Nerual Network_Linear Nerual Network 2)

    1 LMS 学习规则 1.1 LMS学习规则定义 MSE=(1/Q)*Σe2k=(1/Q)*Σ(tk-ak)2,k=1,2,...,Q 式中:Q是训练样本:t(k)是神经元的期望输出:a(k)是神经元 ...

  9. 微信小程序开发-tabbar组件

    "tabBar": { "backgroundColor": "#303133", "color": "#ff ...

  10. 查询Python版本