I had a hard time trying to get a C/C++ WebAssembly component to work in a React application generated from the create-react-app utility. Some blogs suggested using the react-app-rewired package to override the configuration and use the wasm-loader; but I kept getting magic header not detected errors when loading the wasm file or some ES6 syntax errors. Finally I found a StackOverflow post that gave me some ideas on getting it to work.
In this post, I outline the steps I did to create, use a C/C++ WebAssembly in a ReactJS application generated by the create-react-app tool, on a Linux Ubuntu machine. This example will call the WebAssembly's function to add in two numbers (1 and 2) and return the resultant value. The resultant value would be displayed at the top of the web page as shown in the screen shot below.
Create a ReactJS application with create-react-app
- Open up a Terminal. Change to your project directory and type in the following commands to create the ReactJS application cra-wasm-adder.
$ cd /path/to/reactprj/
$ npx create-react-app cra-wasm-adder
The cra-wasm-adder ReactJS application is created.
- Underneath the root of the newly created project, create a source directory, e.g. src_cpp for the C/C++ WebAssembly code.
$ cd /path/to/reactprj/cra-wasm-adder/
$ mkdir src_cpp
The src_cpp directory is created.
Create the C/C++ source code files
- In the newly created src_cpp directory, use a favorite source code editor to create a C/C++ file, e.g. adder.cpp. Enter the following code.
Note: the adder function simply sums up two integer numbers and returns the value.
- Create a Shell script file, e.g. make.sh to call the Emscripten compiler emcc to compile the C/C++ source code.
- In the make.sh file, define the module name and output file names.
- Type in the sed command to replace the import.meta.url string to the WebAssembly file relative to the root of the public directory of the ReactJS project, e.g. /path/to/reactprj/public/.
Note: in this example, the *.wasm file is placed directly underneath the root of the /path/to/reactprj/public/; so the resultant change looks like the code below.
- Type in the sed command to add in the window object to the self.location.href string.
- Type in the sed commands to comment out the dataURIPrefix declaration and isDataURI function block.
- Next, type in the sed commands to modify the wasmBinaryFile variable to point to the actual relative location in the ReactJS' public directory and to remove and replace the getBinary and getBinaryPromise function blocks.
- Finally, type in the sed command to remove the call to the isDataURI function in the instantiateAsync function.
The directory structure should look like the screen shot below:
Run the Shell script
- In a Terminal, change directory to the location of the make.sh shell script.
$ cd /path/to/reactprj/src_cpp/
- Type in the following to run the script.
$ bash make.sh
Create WebAssembly React component
- In a text editor, create the React component under the /path/to/reactprj/src/ directory to use the WebAssembly component, e.g. AddNumbers.js .
Running the ReactJS application
- In a Terminal, run the React JS application.
$ npm run start
The browser opens up the development site.
- Note the message at the top which prints out the result of calling the WebAssembly's adder function: Hello 1+2=3.
The source code for this example is freely available on https://gitlab.com/dominoc925/cra-wasm-adder.