📜 ⬆️ ⬇️

We try to do web-frontend on Rust (WebAssembly)

Recently there was news about the fact that the webassembly is now included in firefox 52 out of the box. And then chrome 57 also pulled up (though there seemed to be some launch bugs). I decided that I should definitely try.


For those who do not know what webassembly is, brief information: webassembly (or wasm) is a low-level language that browsers understand, and into which programs written in popular languages ​​can be compiled. This is much more profitable in terms of parsing and execution than compiling these languages ​​into pure javascript or some asm.js.


Wasm was thought mainly for c / c ++, but, surprisingly, everything is ready to compile the program on rust. Let's make a small application and see what happens. All this will be compiled on Ubuntu. Without theoretical details, just "feel".


Install Rust and emscripten SDK


First we need rustup. This is a tool for installing both the rust compiler itself and other things from the rust world.


curl https://sh.rustup.rs -sSf | sh 

When installing into your ~.profile path to the cargo binaries will be registered, but in order not to log in right now, you can simply execute the command source $HOME/.cargo/env .


Now we need to add the target


 rustup install stable rustup default stable rustup target add wasm32-unknown-emscripten 

emscripten is such an LLVM-to-javascript compiler. Also can generate and wasm. (As you know, Rust uses llvm).


You need to download and unpack sdk for this case. Downloading the emsdk-portable.tar.gz file from http://kripken.imtqy.com/emscripten-site/docs/getting_started/downloads.html#sdk-downloads


Like that:


 mkdir emsdk cd emsdk wget "https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz" tar -xzf emsdk-portable.tar.gz cd emsdk_portable source emsdk_env.sh 

Next you need to compile this thing. I warn you, it may take a couple of hours, and with a wild processor and memory survival.


 emsdk update emsdk install sdk-incoming-64bit emsdk activate sdk-incoming-64bit 

emsdk will offer to execute again
source ./emsdk_env.sh


Hello, world


Let's make a simple hellovorld on a plant


 fn main() { println!("============\nHello, world\n==============="); } 

And compile


 rustc --target=wasm32-unknown-emscripten wasmtest.rs 

The compiler will create a file wasmtest.wasm, as well as a js binding for downloading this file (wasmtest.js), because for now you can’t just take and write <script src="wasmtest.wasm">


Now we need to make a simple html-page for this business.


 <!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8" /> <title>Rust Wasm</title> </head> <body> <script type='text/javascript'> var Module = {}; fetch('wasmtest.wasm').then(response => response.arrayBuffer() ).then(buffer => { Module.wasmBinary = buffer; const script = document.createElement('script'); script.src = "wasmtest.js"; document.body.appendChild(script); }); </script> </body> </html> 

To see the result, the easiest way to start the python http server is that it does not require any configuration.


python -m SimpleHTTPServer


http://localhost:8000/hello.html you http://localhost:8000/hello.html (better in firefox) http://localhost:8000/hello.html you will see the inscription "Hello, world!" In the console.


DOM Access


The console is great, but I would like to display something on the page, this requires some functions of working with the DOM. At first I dug in the brain-documentation, but then I found out that everything was already written before us. There is a webplatform library that provides some basic things for working with the DOM.


Rewrite our program:


 extern crate webplatform; fn main() { println!("============\nHello, world\n==============="); let document = webplatform::init(); let body = document.element_query("body").unwrap(); body.html_set("<h1>, ,  web assembly!</h1> <button> </button>"); let button = document.element_query("button").unwrap(); button.on("click", |_| webplatform::alert(" !")); } 

The whole project can be viewed on github


You can collect it like this:


 cargo build --target=wasm32-unknown-emscripten rustc --target=wasm32-unknown-emscripten src/wasmtest.rs -L target/wasm32-unknown-emscripten/debug/deps/ 

(I'm not really a rasta expert, so if this can be done in one cargo command, tell me pliz).


Then we start our python server.


 python -m SimpleHTTPServer 

And look in the firefox http://localhost:8000/hello.html . It should turn out approximately as in the KDPV.


The compiled files and hello.html also lie in the repository, so you can just feel the result for yourself without bothering with the compilation.


Conclusions and perspectives


It is clear that now everything is raw, uncomfortable and with bugs, but the webassembly has a great future. Anything that requires complex calculations can be transferred from javascript to wasm. There will be heavy programs on the web, which we now can not even dream of. Heaped games? Video and audio processing? Who knows.


A bunch of libraries on c, c ++, rust, etc. will be transferred to the web in the form of wasm-modules.


There are enthusiasts who want to speed up reactjs with rust and wasm ( link ).


A closed proprietary code will appear. If js passed through uglifyjs can still be read somehow, then it would be much more difficult to do with c wasm.


As always, welcome to comments. What do you think?


')

Source: https://habr.com/ru/post/325008/


All Articles