Introduction
WebAssembly is a new type of code that can be run in modern web browsers - it is a low-level assembly-like language with a compact binary format that runs with near-native performance and provides languages such as C/C++ with a compilation target so that they can run on the web. It is also designed to run alongside JavaScript, allowing both to work together.
I previously wrote an article about how to develop WebAssembly using Golang - WebAssembly: An Essential Skill for Future Front-end Development.
Both Rust and Go can be used to develop WebAssembly, but they have their own advantages and disadvantages.
Rust’s advantages:
- Faster performance and smaller binary files
- Better memory safety
Go’s advantages:
- Easier to get started and learn
- Better ecosystem and community support
Overall, if you prioritize performance and memory safety, then Rust might be the better choice. If you value development efficiency and ease of use, then Go might be more suitable for you. Of course, the actual choice should be based on specific project requirements and team circumstances.
Due to some work requirements, I’ve recently been working on some Rust projects, and I’d like to systematically document it here. I hope this can be helpful when you encounter scenarios that prioritize performance and memory safety.
Environment
- Rust 1.70.0
- wasm-bindgen 0.2.87
Create Project and Add Dependencies
This assumes Rust is already installed. If you need to install it, please refer to the official website.
Use Cargo to create a project named hello-wasm
:
|
|
Enter the project, open the Cargo.toml
file, and add dependencies:
|
|
Update lib.rs
In the default project creation, there’s a file named lib.rs
. Replace all its content with:
|
|
Compile
At this point, we’ve created the simplest function - one that returns the sum of two integers.
Now we can proceed with compilation. Before compiling, we need to install a tool called wasm-pack
:
|
|
Then compile:
|
|
After compilation, a pkg
folder will be created with the following content:
|
|
Although there are many files, we can see the wasm file we need, and based on Go’s wasm import method, we might need to use the js file here.
Frontend Integration
To quickly verify, let’s create an index.html
file directly in the hello-wasm
project for frontend integration.
1. Create index.html
First, create an index.html
file:
|
|
Yes, that’s right! This is a standard opening! đŧ
2. Import WASM
Unlike Go’s wasm import method, Rust prefers to directly import the js file rather than having developers manually import the wasm file.
Here we use js import:
|
|
3. Complete Code
The complete HTML code is as follows:
|
|
Verification
Here we can quickly start an http server. I choose to use http-server
, but you can also use methods like python3 -m http.server
, depending on your personal preferences.
So, start the http server:
|
|
Open your browser, visit http://localhost:8080
, open the debugger, and you should see the output the result from rust is: 3
, which means we’ve taken the first step in doing some fancy stuff!
Common Issues
1. Frontend Reports Response Type Error
The detailed error is as follows:
|
|
You might encounter this error when importing the js file generated by WebAssembly. At first glance, it seems to be an http server response issue, and when searching, you might find posts saying it’s a response problem.
In fact, when following this article step by step, you won’t encounter this problem because the compilation parameter in this article directly solves this issue. When I was figuring this out on my own, solving this problem really drove me crazy…
The key lies in the --target
parameter of the compilation command.
When this parameter is not set, the default is actually --target bundler
, which compiles for use with scaffolds like webpack. Therefore, using --target web
here compiles it for direct use in the web.
The relevant parameters are as follows:
- bundler: Compile for use with scaffolds like webpack
- web: Compile for direct use in web
- nodejs: Compile into a node module that can be loaded via require
- deno: Compile into a deno module that can be loaded via import
- no-modules: Similar to web, but older and cannot use ES modules
2. Directly Importing the WASM File
If you try to directly import the wasm file instead of using the method described in this article, you’ll find that it works too!
|
|
Yes, that’s right, it works for now, but when you introduce other things like DOM manipulation, it starts to break…
3. Updated WASM Import Method
Regarding the previous issue, let’s not discuss whether we can directly import the wasm file. Here, I’ll just mention the instantiateStreaming
method. This is an updated method that doesn’t require conversion to arrayBuffer
, which I discovered while exploring Rust projects. If you’re importing wasm in other languages, please use this updated method.