2022年2月5日土曜日

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

https://zenn.dev/oberk/articles/c64c856e006012
シェアしました。


はじめに

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

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

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

と表示されます。

こちらの公式チュートリアルがわかりやすいです

ベンチマーク

benchmark

こちらのベンチマークがありました。速度面でですが一応タイトル回収です。でも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などもサポートしているので開発には使いやすいです。

最後に

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

この記事に贈られたバッジ

 

0 コメント:

コメントを投稿