Web Assembly 만들어 보기

2023. 4. 15. 00:51Language/Rust

Rust를 공부하다 보니 가장 많이 연관되는게 WebAssembly라 튜토리얼을 한번 따라 해봤습니다.

Web Assembly??

Web Assembly는 Javascript만으로는 어려웠던 고성능의 애플리케이션을 C, C++, C#, Rust 등을 사용하여 웹이지만 네이티브에 가까운 속도로 실행 가능하게 만드는 것입니다.

정확한 원리는 잘 모르지만, 제가 생각 할 때는 다른 언어로 개발하고 컴파일하면 wasm이라는 파일이 나오게 되는데, 웹에 접속하면 자동으로 wasm이라는 파일을 다운받아 브라우저 위에서 wasm을 실행시키기 때문에 빠른 것으로 보입니다.

이름이 Web Assembly이지만 막상 만들고 나니 브라우저 뿐만 아니라 wasm 파일이 리눅스, 윈도우, IoT 등 다양한 플랫폼에서 돌아간다는 것을 발견하여, 최근에는 브라우저 내에서 실행 되는 것을 넘어 파일 시스템 접근, 네트워크 통신, 시스템 자원 접근 등 할 수 있는 방법을 연구 중입니다.

WASI(Webassembly System Interface)라고 최근에 활발히 개발 중인 것으로 보입니다.

Why Rust??

WebAssembly를 개발 할 때 가장 많이 사용되는 언어를 조사 한 것으로 Rust가 압도적으로 1위 인것이 보입니다.

Web Assembly의 가장 큰 단점 중 하나가 처음 웹 사이트에 접속 할 때 화면이 뜨는 속도가 느리다는 것입니다.

그 이유는 최초 접근 시 wasm이라는 파일을 다운 받아 실행 해야하기 때문에 처음 접속할 때 화면이 뜨기까지 꽤 시간이 걸리는 문제가 있습니다.

하지만 Rust는 가비지 컬렉션이 없기 때문에 다른 언어들에 비해 파일이 매우 작습니다. Go로 개발하게 되면 2MB가 넘는게 Rust로 개발하게 되면 1.46KB 밖에 되지 않습니다.

또한 브라우저 환경에서는 메모리 관리가 중요한데 Rust는 메모리에 굉장히 안정적이라 인기가 많은 것 같습니다.

튜토리얼 따라하기

https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm

프로젝트 생성

먼저 Webassembly를 하기 위해서는 wasm-pack을 설치해야 합니다.

$ cargo install wasm-pack

그리고 cargo로 새로운 프로젝트를 생성합니다.

$ cargo new --lib hello-wasm
$ cd hello-wasm
$ code .

hello-wasm이라는 프로젝트를 생성하고 code . 을 통해 VS Code를 실행 시켰습니다.

일반적으로 lib 형태의 프로젝트가 생성되었습니다.

여기서 lib.rs의 내용을 필요하지 않기 때문에 전부 지웁니다.

Cargo.toml 설정

[package]
name = "hello-wasm"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate-type=["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

위와 같이 lib와 dependencies를 설정합니다.

wasm-bindgen는 javascript와 wasm의 연동시켜주는 라이브러리라고 생각하면 됩니다.

lib.rs 작성

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern { // Rust에서 javascript 함수 실행
    pub fn alert(s: &str); //window.alert를 의미
}

#[wasm_bindgen]
pub fn greet(name: &str) { // javascript에서 rust 함수 실행
    alert(&format!("hello, {}!", name));
}

lib.rs를 작성합니다. 위 코드를 보면 대충 감이 오겠지만 extern은 rust에서 javascript를 접근하는 부분이고, pub fn는 javascript에서 rust를 접근하는 부분입니다.

뒤에 나오는 index.html에서 javascript가 Rust의 함수를 실행 시킬 때는 pub fn greet를 실행하게 됩니다.

index.html 추가

<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>hello-wasm example</title>
  </head>
  <body>
    <script type="module">
      import init, { greet } from "./pkg/hello_wasm.js";
      init().then(() => {
        greet("WebAssembly");
      });
    </script>
  </body>
</html>

index.html 파일을 추가하고 위와 같이 작성합니다.

WebAssembly 빌드

$ wasm-pack build --target web

빌드를 하게 되면 pkg 폴더가 생성됩니다. 열어 보면 wasm 파일이 생성 된 것을 볼 수 있습니다.

WebAssembly 실행

Web 어플리케이션을 실행시키기 위해서는 Web Server가 필요합니다. 여러 방법이 있지만 가장 간단하게 VS Code에서 live Server를 설치하여 실행하도록 하겠습니다.

VS Code 확장에서 Live Server를 검색해서 설치하면 됩니다.

그리고 index.html로 가서 마우스 우측 키를 누르면 아래와 같이 나오는데 Open with Live Server를 클릭합니다.

Web에서 확인

 

실행 시켜 보면 Alert가 뜨는 것을 확인 할 수 있습니다.

 

그리고 F12를 눌러 네트워크로 들어가보면 wasm 파일을 다운 받을 것도 확인 할 수 있습니다.

'Language > Rust' 카테고리의 다른 글

Rust의 Trait  (0) 2023.05.11
Rust 설치 및 VS Code 셋팅(Linux, Debian)  (0) 2023.04.26
Rust Option의 메서드 알아보기  (0) 2023.04.01
Rust 소스 코드 문서화  (0) 2023.03.21
Rust 열거형(Enum)  (0) 2023.03.20