3
Help us understand the problem. What are the problem?

posted at

updated at

Rust + Yew で静的ページをGitHub Pagesにデプロイ

Yewは、Rustとwasmを使ってReactのようなコンポーネントベースのWebフロントエンドを構築できるフレームワークです。

Yewを使って、静的ページをGitHub Pagesにデプロイしてみます。

環境

  • Windows 11 WSL2 Debian bullseye
  • Docker version 20.10.11
  • docker-compose version 1.29.2
  • Rust 1.58
  • Yew 0.19
  • Trunk 0.14.0

ソースコード

今回使用したソースコードは、環境構築に利用したDockerfile等も含めて下記のリポジトリにあります。

静的ページの構築

まずはDockerを使ってローカル環境上にYewプロジェクトを構築していきます。

$ docker run \
  --interactive --tty --rm \
  --volume $(pwd):/app \
  --workdir /app \
  rust:1.58-slim \
  cargo new yew-static-pages
$ cd $_

Dockerfiledocker-compose.ymlを作成します。

Dockerfile
FROM rust:1.58-slim
WORKDIR /app

RUN apt-get update && apt-get install -y \
    git \
    curl \
    build-essential \
 && rm -rf /var/lib/apt/lists/*

# setup yew
RUN rustup target add wasm32-unknown-unknown
RUN cargo install trunk

COPY ./ ./
RUN cargo build

CMD trunk serve
docker-compose.yml
version: '3'
services:
  app:
    build: .
    volumes:
      - ./:/app
    environment:
      - USER=root
    ports:
      - 8080:8080

Cargo.tomlに、Yewへの依存を追記します。

Cargo.toml(抜粋)
[dependencies]
yew = "0.19"

Yew公式のテンプレートを参考に、とりあえずHello Worldを表示するページを作ります。

src/main.rs
use yew::prelude::*;

fn main() {
    yew::start_app::<App>();
}

#[function_component(App)]
pub fn app() -> Html {
    html! {
        <main>
            <img class="logo" src="https://yew.rs/img/logo.png" alt="Yew logo" />
            <h1>{ "Hello World!" }</h1>
            <span class="subtitle">{ "from Yew with " }<i class="heart" /></span>
        </main>
    }
}

index.htmlを配置します。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Yew App</title>
  </head>
</html>

$ docker-compose up --build を実行して、 localhost:8080 でWebサイトが表示されれば成功です。

GitHub Pagesへのデプロイ

$ trunk build --releaseで生成されるdist/index.htmlを、GitHub Pages上で閲覧できるようにデプロイします。--public-urlオプションでGitHub Pagesのパスを指定する点に注意です。

github/workflows/gh-pages.yml
name: Deploy

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - run: rustup target add wasm32-unknown-unknown
    - run: cargo install trunk
    # 「yew-static-pages」は実際のリポジトリ名に変更
    - run: trunk build --release --public-url yew-static-pages
    - run: cp -r ./dist/ ./public/
    - uses: peaceiris/actions-gh-pages@v3
      if: ${{ github.ref == 'refs/heads/main' }}
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./public

GitHubにpushした後、しばらくしてデプロイが完了し、https://<ユーザ名>.github.io/<リポジトリ名>でページが表示されたら成功です。

image.png

wasm-packを使う場合

wasmのビルドにはTrunkではなくwasm-packも選択できます。Trunkとの比較など詳細は公式ドキュメントを読んでください。

wasm-packを使う場合、ビルド時に.gitignoreが自動的に配置され、GitHub上でコミットに含まれずGitHub Pagesにリリースされません。GitHub Pagesに反映するためには.gitignoreを削除する必要があります。

.github/workflows/gh-pages.yml(抜粋)
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - run: cargo install wasm-pack
    - run: wasm-pack build --release --target web --out-name wasm --out-dir ./public
    - run: cp ./static/index.html ./public/index.html
    - run: rm -rf ./public/.gitignore

    - uses: peaceiris/actions-gh-pages@v3
      if: ${{ github.ref == 'refs/heads/main' }}
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: ./public

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
3
Help us understand the problem. What are the problem?