☢️

Rustでフロントエンド with Dioxus ~環境づくり~

2024/08/18に公開

ここ数ヶ月、趣味でRustを使ってCLIツールなどを作っていましたが、最近はフロントエンドもRustで書けるということを知り、興味を持ちました。そこで、クロスプラットフォームのWebフレームワークであるDioxusを使ってみることにしました。

Dioxusって?

https://dioxuslabs.com/

Dioxusは、Rustで書かれたWebフレームワークです。WebAssemblyを使ってフロントエンドをRustで書くことができます。また、Dioxusはクロスプラットフォームであるため、Webアプリケーションだけでなく、デスクトップやモバイル、TUI[1]のアプリケーションもRustで書くことができます。

ではでは、早速環境づくりをしていきます。

環境づくり

環境構築はprotoを使ってみました。protoは、プログラミング言語やその他ツールのバージョンマネージャーです。WindowsでもMacでも使えるのがお気に入りで、個人的な開発環境ではだいたいこれを使っています。(今回はRustのみなので、そこまでprotoを使う旨味はないかもですが……)

protoのインストール

参考リンクはこちら

Windowsの場合

PowerShellで以下のコマンドを実行します。

irm https://moonrepo.dev/install/proto.ps1 | iex

Macの場合

事前にGit/tar/unzip/gzip/xzのインストールが必要です。brewを使ってインストールです。

brew install git unzip gzip xz

次に、以下のコマンドを実行します。

curl -fsSL https://moonrepo.dev/install/proto.sh | bash

rustupとRustのインストール

rustup

Windowsの場合は、こちらからインストーラをダウンロードして実行します。

Macの場合は、以下のコマンドを実行します。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Rust

protoを使ってRustのインストールです。この時に、インストールするRustのバージョンが指定できます。今回は1.80.1を指定します。

proto install rust 1.80.1

rust-toolchain.tomlの作成

rust-toolchain.tomlを作成します。このファイルを使うと、プロジェクトごとにRustのバージョンやビルドターゲットなどが指定できます。
プロジェクトのルートディレクトリにファイルを作成して、以下の内容を記述します。

rust-toolchain.toml
[toolchain]
channel = "1.80.1"
targets = ["wasm32-unknown-unknown"]

Dioxus CLIのインストール

以下のコマンドを実行して、Dioxus CLIをインストールします。

cargo install dioxus-cli

(ビルドが走るので、結構時間がかかります……)

プロジェクトの作成

Dioxus CLIを使ってプロジェクトを作成します。
プロジェクトのルートディレクトリに移動して、以下のコマンドを実行します。

dx init

質問が表示されるので、回答します。ここでは、以下のように回答しました。

  • Which sub-template should be expanded? : Web
  • How do you want to create CSS? :Tailwind
  • Should the application use the Dioxus router? : true

プロジェクトのビルドとプレビュー

最後に、プロジェクトをビルドしてプレビューします。
プロジェクトのルートディレクトリに移動して、以下のコマンドを実行します。

dx serve

(ここでもビルドが走るので、結構時間がかかります……)

ビルドが完了すると、http://localhost:8080でプレビューが確認できます。


プレビュー画面

ソースコードの整理

バージョンにもよりますが、ここまでで、プロジェクトのディレクトリ構成は以下のようになっています。

├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── Dioxus.toml
├── README.md
├── assets
│   ├── favicon.ico
│   ├── header.svg
│   └── main.css
├── dist
│   └── <ビルドされた静的コンテンツたち>
├── input.css
├── rust-toolchain.toml
├── src
│   └── main.rs
├── target
│   └── <Rustのアーティファクトたち>
└── tailwind.config.js

スッキリした状態から始めたいので、少しファイルを整理していきます。

不要なファイルの削除

以下のファイルを削除します。

  • assets/favicon.ico
  • assets/header.svg
  • assets/main.css

assetsディレクトリは空になるので、.gitkeepファイルでも置いておきます。

main.rsの編集

src/main.rsを以下のように編集します。

src/main.rs
#![allow(non_snake_case)]

use dioxus::prelude::*;
use dioxus_logger::tracing::{info, Level};

fn main() {
    // Init logger
    dioxus_logger::init(Level::INFO).expect("failed to init logger");
    info!("starting app");
    launch(App);
}

fn App() -> Element {
    rsx! {
        Router::<Route> {}
    }
}

#[derive(Clone, Routable, Debug, PartialEq)]
enum Route {
    #[route("/")]
    Home {},
}

#[component]
fn Home() -> Element {
    rsx! {
        h2 { "Hello, World!" }
    }
}

エントリーポイントのmain関数、メインとなるApp構造体、ルート定義のRouteと、Homeコンポーネントの定義のみになりました。🧹スッキリしましたね。

画面はこんな感じ。


スッキリした画面

おわりに

今回は、Dioxusを使ってフロントエンドをRustで書くための環境構築をやってみました。今時点でのディレクトリ構成はこんな感じ。

├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── Dioxus.toml
├── README.md
├── assets
│   ├── .gitkeep
├── dist
│   └── <ビルドされた静的コンテンツたち>
├── input.css
├── rust-toolchain.toml
├── src
│   └── main.rs
├── target
│   └── <Rustのアーティファクトたち>
└── tailwind.config.js

参考として、以下のGitHubリポジトリにコードをアップしています。

https://github.com/sakai-nako/dioxus-study

次回からは、実際にコンポーネントを作っていきます。

おまけ:Dioxusのα版を使う

これを書いている2024年8月現在、Dioxusのバージョンは0.5で、α版として0.6がプレリリースされています。
0.6.0-alpha.2のリリースノートを見てみると、なかなか魅力的なアップデートがたくさんあったので、私はこっちを使っています。(CLIのCargo Workspace対応が地味に嬉しい)

α版の導入方法としては、以下の3点を実施すれば使えます。参考リポジトリでもα版を使っています。

  • 以下のコマンドを実行して、Dioxus CLIのバージョンを0.6.0-alpha.2に変更
    • cargo install dioxus-cli --version 0.6.0-alpha.2
  • Cargo.tomldioxusのバージョンを0.6.0-alpha.2に変更
  • (環境によっては必要となる可能性があります)Cargo.tomlwasm-bindgen = "=0.2.92"を追加
    • 私の環境で、Dioxus CLIのバージョンが0.6.0-alpha.2の場合、wasm-bindgenのバージョンが0.2.92でないとビルドが通りませんでした。これのおかげで数時間が溶けました😇
      • (2024/9/22追記)Dioxus CLIをインストールし直すと、wasm-bindgenのバージョンを指定しなくてもビルドが通るようになりました。
脚注
  1. TUIはTerminal User Interfaceの略で、ターミナル上で動作するGUIのことです。 ↩︎

Discussion