🦀

Yewとは ~Rust+wasmで始めるweb開発でReactに勝つ?~

2021/03/01に公開

はじめに

zenn初投稿の普通科高校生です。

Yewが素晴らしいので日本人の使用者がもっと増えればいいなと思います

Yewとは

https://github.com/yewstack/yew
YewはマルチスレッドなWebフロントをWebAssemblyを使って作ることができるRustのフレームワークです。

  • npm資産とRust/C資産の相互運用性
  • 仮想DOMを使った効率のいいレンダリング
  • JSXライクなHTMLマクロ

をメリットとしています。

WebAssemblyとは

WebAssemblyはブラウザで動くコンパイル可能な低レベル言語です。JavaScriptにくらべ高速な計算はできます。
まだ、DOMの呼び出しは遅い(JSを一度経由するため)ですが、今後早くなる予定です。

なぜ Rust?

Rustは素晴らしいコンパイラと型システム、所有権により安全なコードを書くことができます。
StackOverflowによる調査で五年連続で最も愛されている言語です。
WebAssemblyには今の所GCがないので、RustのようなGCのない言語のほうがファイルサイズが小さくなります。

Yewの紹介

yewのhtml!マクロ

YewにはJSXのようなマクロがあります。

struct Model {
    link: ComponentLink<Self>,
    value: i64,
}

//--------------------------実際はここにまだにあります----------------------

fn view(&self) -> Html {
    html! {
        <div>
            <button onclick=self.link.callback(|_| Msg::AddOne)>{ "+1" }</button>
            <p>{ self.value }</p>
        </div>
    }
}

web_sys

web_sysはRustからDOMを触るためのラッパーです。
基本yewから直接DOMを触ることはありませんがcanvasとかを使うときに有用です。。

use wasm_bindgen::prelude::*;
// エントリーポイント
#[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> {
    let window = web_sys::window().expect("no global `window` exists");
    let document = window.document().expect("should have a document on window");
    let body = document.body().expect("document should have a body");

    // 要素の作成
    let val = document.create_element("p")?;
    val.set_text_content("Hello from Rust!");

    body.append_child(&val)?;

    Ok(())
}

このコードだけで Hello from Rust! を表示できます。

JavaScriptを使う ~npm資産の引き継ぎ~

Rustのクレート wasm_bindgenをつかってJavaScriptを使うことができます

function greet(text) {
	console.log(text);
}
#[wasm_bindgen(module = "/index.js")]
extern "C" {
	fn greet(text: String);
}

これでgreet関数をRustから使えるようになります。
個人的にwebの世界でJSの資産は大きいと思うのでシンプルですがこのような機能があるとありがたいです。

Yewのライフサイクル

LifeCycle

下位のコンポーネントにも適用されるのでデータをやり取りする場合CallBackを使って渡します。

Vectorを使う

YewではVectorに入れたものをイテレータで表示することができます

fn view(&self) -> Html {
    let vegetable = vec!["Tomato".into(), "Strawberry".into(), "Onion".into()];
    html! {
        for vegetable.iter().map(|text|
        html! {
            {text.clone()}
            <br/>
        }
        );
    }
}

Tomato
Strawberry
Onion

と表示されます。

こちらの公式チュートリアルがわかりやすいです
https://yew.rs/docs/ja/getting-started/project-setup

ベンチマーク

benchmark

https://github.com/DenisKolodin/todomvc-perf-comparison/

こちらのベンチマークがありました。速度面でですが一応タイトル回収です。でもReact資産使えんじゃんって方もご安心ください。

クレート

YewからReactのコンポーネントを使えるようにするクレートです。
使ってみましたが、使える状態ではないです。作者がこのプロジェクトの未来に期待していると書いてあったので一応書きました。
ぜひ整備して発展してもらいたいです。

JavaScriptに依存しないYewのスタイルフレームワークです。
カードやアイコン、フォーム、カールセルなどの基本的なコンポーネントがあります。

Bulma CSSをYewで使うためのクレートです。

ReduxのYew版です。
共有状態を作ったり、localStorageを使って永続化をしたりできます。

yew版マテリアルウェブコンポーネントです。
使うとき少しコツがいります。

Trunk

上の公式ページだと

wasm-pack build --target web --out-name wasm --out-dir ./static

でコンパイルし、サーブする必要があります

Rust製の trunk というツールを使えば

trunk serve

で済み、SCSSなどもサポートしているので開発には使いやすいです。
https://github.com/thedodd/trunk

最後に

他にもYewには SSR fetchAPI ルーターなどありますので、今後も機会があれば書きたいと思ってます。
ぜひ、Yewを使ってみてください。
誤字訂正、質問などありましたらぜひ。

Discussion