Zenn
😔

【Rust】YewとAxumの連携

2025/01/03に公開

YewYewで作ったWebWebアプリケーションをAxumAxumで作ったWebWebサーバーで公開する

YewYewは、「WebWebアプリケーションフレームワーク」です。

https://yew.rs/ja/

一方AxumAxumは、「WebWebアプリケーションフレームワーク」です。

https://github.com/tokio-rs/axum

🤔🤔🤔

二者の区別

そもそもWebWeb技術には、表裏の別があります。ブラウザーに表出して見える箇所、つまるところ画面を形作るものを「frontfront endend」と、通信など、ブラウザーからは見えない裏側を「backback endend」と称されています。

frontfront endendの例は比較的明確で、JavaScriptJavaScriptTypeScriptTypeScriptWebAssemblyWebAssemblyといった言語が代表的です。論うまでもないと思っていましたが、HTMLHTMLCSSCSSもこれに該当するようです。
対してbackback endendは、あらゆる言語によって行われています。個人的に親近なものは、PythonPythonFlaskFlaskです。

YewYewfrontfront endendです。主に、HTMLHTMLの埋め込みCSSCSSの設定といった、基本的な画面構成を実装します。ただし、画面の動きは他のものに委ねています。
今ホームページを読んでいて初めて知りましたが、yew_routerというものを使えばbackback endendらしい実装もできるようです紛らわしいですね。

反対にAxumAxumbackback endendです。主に、HTTPHTTPが云云という箇所を実装します。基本的に画面には関与しません。

YewYewを使う意義

YewYewは、「WebAssemlyWebAssemlyの利用を簡略化するもの」としても使い得ます。

本記事では特に述べませんが、WebAssemlyWebAssemlyを使うには幾つもの手順を踏む必要があります。そうしたあらゆる手順を

trunk serve

というコマンド一つで代替できると言えば、まるで融通利くもののように聞こえましょうか。この利点を応用できれば、WebAssemlyWebAssemlyに親しむ機会も作りやすくなろうと考えた次第であります。本記事では、その応用先としてAxumAxumを選定しています。

本題

私事ですが、以前投稿した記事にてYewYewを使ったアプリケーションを作りました。本記事では、アプリケーションの具体的な作り方はこれを述べてございません。拙作を流用せられても構いませんので、何らかのアプリケーションをあらかじめご用意ください。

また、試行の上で次の記事を拝見し、参考にさせて頂きました。

https://zenn.dev/scirexs/articles/bcf695494632dc

準備

YewYewアプリケーションを実行すると、フォルダー内にdistというフォルダーが自動生成されます。この中に、あらかじめ用意するindex.htmlファイルと、生成された.jsファイル、.wasmファイルが存在するはずです。このdistフォルダーをそのまま移植するなどして流用します。

実装

  1. packagepackage作成

    with_yewの名前で作成します。

    package作成
    cargo new with_yew
    

    with_yewフォルダーが生成されるので、今回はdistフォルダーをこの中に移植します。

  2. cratecrate追加

    Cargo.toml
    [dependencies]
    axum = { version = "0.8.1", features = ["http2"] }
    tokio = { version = "1.42.0", features = ["full"] }
    tower-http = { version = "0.6.2", features = ["fs", "trace"] }
    

    コマンドで追加する場合は次のようにします。

    crate追加
    cargo add axum --features http2
    cargo add tokio --features full
    cargo add tower-http --features fs --features trace
    
  3. ソースコード記述

    with_yew/src/main.rsに次の通り記述します。

    main.rs
    use tower_http::{services::ServeDir, trace::TraceLayer};
    use axum::Router;
    use tokio::net::TcpListener;
    
    #[tokio::main]
    async fn main() {
        const STATIC_DIR: &str = "./dist";
    
        let serve_dir: ServeDir = ServeDir::new(STATIC_DIR);
    
        let app: Router = Router::new().nest_service("/dist", serve_dir);
    
        let listener: TcpListener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
    
        axum::serve(listener, app.layer(TraceLayer::new_for_http())).await.unwrap();
    }
    
    要点

    殆ど参考記事の通りなので敢えて述べるようなことはありません。一部、サンプルプログラムを参考に変更した箇所もありますが、一箇所注意点があります。

    nest_service("/dist", serve_dir)にて、移植したフォルダー名を基に"/dist"と指定しています。私の試した限りでは、斯くしなければ動きませんでした。

    次に、.htmlファイルを修正します。私の場合は、distフォルダー内に次のようなファイルが存在します。

    PS C:\\with_yew> ls .\dist\
    
        Directory: C:\\with_yew\dist
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -a---      2023/12/11()     2:26        1478457 bmi_calculator-c3e78f12e3a455f2_bg.wasm
    -a---      2023/12/11()     2:26          25420 bmi_calculator-c3e78f12e3a455f2.js
    -a---      2025/01/03()     6:21           1445 index.html
    

    修正するのは、(更新日が新しい通り)index.htmlです。参考記事のおっしゃるように、.jsファイルと.wasmファイルの指定を変えなければなりませんでした。./フォルダー名/ファイル名の型式にすることで、正しく動作します。

    index.html(抜粋)
    <link rel="preload" href="./dist/bmi_calculator-c3e78f12e3a455f2_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
    <link rel="modulepreload" href="./dist/bmi_calculator-c3e78f12e3a455f2.js">
    <script type="module">import init from './dist/bmi_calculator-c3e78f12e3a455f2.js';init('./dist/bmi_calculator-c3e78f12e3a455f2_bg.wasm');</script>
    
  4. 実行

    移植元はYewYewですが、今作成したものはYewYewではないので、trunk serveは使いません。

    実行
    cargo run
    

    ブラウザーでhttp://127.0.0.1:8080/distに接続すると、YewYewで作成したアプリケーションがその通り表示されるはずです。

    証明書などは使用していないのでprotocolprotocolhttpIPIP addressaddressportport番号は、TcpListener::bind("127.0.0.1:8080")としたので127.0.0.1:8080directorydirectory部はnest_service("/dist", serve_dir)としたので/distとなります。

YewYewで生成したWebAssemblyWebAssembly製アプリケーションが、以上のように移植し得ることを確認しました。但し、移植の自動化については確認していません。また、YewYewは依然として開発途上のため、インターネットへ公開するような運用を推奨していない⋯と、どこかで読んだ記憶があります。セキュリティー上、斯様に移植してよいのかは疑問です。

Discussion

ログインするとコメントできます