Cause#
When I was a freshman, I did a certain course assignment, and my topic was the life of the game. Since then, I have wanted to implement one myself. But I have always put it off and haven't started yet. Recently, I have been learning Rust and happened to come across a very good tutorial. This is the cause of this project.
Process#
Preparations#
I use the vscode+wsl2 environment. Overall, except for the high memory usage due to machine performance limitations, the experience is still good.
However, I encountered three problems when setting up the project environment.
- npm install failed
- Solution: Install npm in Ubuntu
- Reference: Unable to use npm in WSL
- wasm-build failed
- Solution:
[package.metadata.wasm-pack.profile.release] wasm-opt = false
- Reference: failed to download binaryen-version_90-x86-windows.tar.gz
- wasm-pack test --chrome --headless failed
- Solution: Use
wasm-pack test --chrome
instead - Reference: Headless Chrome test fails
Coding#
During the coding phase, I followed the tutorial, which went smoothly. However, the code in the tutorial was all placed together. This doesn't look very comfortable and is not suitable for my subsequent iterations. I spent some time modularizing it. But the tutorial also explains the reason for not modularizing: Shrinking .wasm Size. This made me realize that I still need to optimize and modify according to the characteristics of the project.
Deployment#
During development, I found that shalzz/wasm-game-of-life provides a live demo. It is deployed using Vercel. I have used Vercel before, but only for one-click deployment by others. I found it quite interesting, so I decided to give it a try. It took some time and encountered some difficulties. Let me explain the process here.
- At first, I referred to Deploying a WASM-Powered React App on Vercel. Later, I found that it was not necessary to be so complicated because I had already
wasm-pack publish
, so I could directly import wasm-game-of-life-euds63 - npm as a dependency. This way, I only need to deploy webpack without installing Rust-related content again. - After making the corresponding modifications to the code, I started to try to deploy. First, I encountered a path problem, so I changed the
Root Directory
to www. - At this time, Vercel showed that the deployment was successful, but it actually couldn't run. Based on my previous experience, I instinctively thought it was also a path problem. I started to modify the paths in other places. But it wasn't. After modifying it several times, I found that: the wrong path would lead to a successful deployment, while the correct path would cause
npm install
to fail. And what I initially thought was the wrong path was actually correct. I think this step was caused by me not looking at the logs carefully. - According to the corresponding error, I found that it was a node version issue. The node version that ran successfully on my local machine was 12, while Vercel only supports 18 and 16. My initial idea was to install another version of 12, but it didn't work. Later, with the idea of giving it a try, I changed it to 16, and surprisingly,
npm install
succeeded. - After
npm run build
, an error occurred: Missing Public Directory. According to Error List | Vercel Docs, I tried settingOutput Directory
to dist, and the problem was solved.
Configuring the Domain Name#
I used subdomain configuration. I used to think that configuring subdomains was quite magical. After trying it myself, I found that it seems to be equivalent to a redirect?
First, I added a CNAME record in my DNS service provider.
SUBDOMAIN | TYPE | VALUE | TTL, SEC |
---|---|---|---|
lifegame | CNAME | game-of-life-2hpx.vercel.app | 86400 |
Then, in the corresponding project in Vercel, I added the domain name lifegame.ds63.eu.org.
At first, there was no SSL certificate set up. I looked up some information online and found that Vercel would automatically provide an SSL certificate. I thought there was something wrong with my own settings. It turned out that I had to wait for a while.
Gains#
- Rust custom macros
- Steps
- Define and export custom macros in a module
// utils.rs #[macro_export] macro_rules! log { ( $( $t:tt )* ) => { web_sys::console::log_1(&format!( $( $t )* ).into()); } }
- Use in other modules
// lib.rs #[macro_use] mod utils; mod universe; // universe.rs use crate::utils; // Use directly log!("This is a log message: {}", some_variable);
- Define and export custom macros in a module
- Steps
- Always let profiling guide your focus
- Some performance profiling tools
- Edge Developer Tools -> Performance
cargo benchcmp
perf
- Time Profiling - Rust and WebAssembly is worth reading again a few times
- Some performance profiling tools
- Vercel deployment
References#
- Rust and WebAssembly
- Play John Conway’s Game of Life The best implementation of Game of Life I have found so far
- shalzz/wasm-game-of-life: Game of Life implementation using Rust, Javascript and WebAssembly!
- Projects Overview | Vercel Docs