elm-spa+elm-ts-interop+FirebaseでストV用のメモツールを作ってみた
2022年09月05日(月)

作った物


https://sfv-speedmemo.pages.dev/

  • ストリートファイターV用のメモツール
  • 自分の使用キャラを選択し、対戦キャラ毎にメモを追加できる
  • Firebaseで管理しているのでPCとスマホで情報を共有できる

作った理由

  • ランクマのロード時間中にさくっと見返したりメモするため
  • TheSacredLiptonが一般公開しているelmのプロダクトがなかったため
  • elm-ts-interopを試してみたかったため


開発期間

  • 9/1~9/4の四日間
  • elmで速度を出しながらカジュアルかつ堅牢に書けたのはelm-spa+elm-ts-interop+firebaseの組み合わせがいい感じにマッチしたからと感じる
  • 速度重視である程度手抜きしながら作ったがelmを使っているため後から変更しやすい安心感があり技術的負債がたまっている感じがしなかった


今回やらなかったこと

  • テストコード
  • UIデザイン
  • エラー処理関連...特にinteropのtoElmを受け取る処理はこんな感じでかなり手抜きしている、ReplaceMeはelm-spaで自動生成される何もしない処理だが私は後回しにしたい処理のところに使ったりする。おすすめはしない。
subscriptions : Model -> Sub Msg
subscriptions model =
    InteropPorts.toElm
        |> Sub.map
            (\resultToElm ->
                case resultToElm of
                    Result.Ok toElm ->
                        case toElm of
                            InteropDefinitions.GetCharacterToElm f ->
                                GetCharacterToElm f


                            _ ->
                                ReplaceMe


                    Result.Err err ->
                        ReplaceMe
            )


利用技術&サービス


Firebase Authentication

  • 認証にはGoogleログインのみ利用


Firebase RealtimeDatabase

  • 同接100人以上になる予定がないため利用
  • リアルタイム要素は必要無いがプロトタイプとしての使い勝手が良いのでFirestoreではなくこちらを利用


Firebase Local Emulator Suite

  • ローカル環境で検証できるので利用。とても便利


elm-spa v6

  • まだelm-spa v6の機能が揃っていないのでelm-landは使わない
  • Routeをファイルベースで管理&自動生成できるので便利
  • ログインページヘの自動遷移等の設定もできるので便利
beforeProtectedInit : Shared.Model -> Request -> ElmSpa.Protected User Route
beforeProtectedInit shared req =
    case shared.uid of
        Just uid ->
            ElmSpa.Provide uid


        Nothing ->
            ElmSpa.RedirectTo Gen.Route.SignIn


elm-ts-interop

  • フリー版のコミュニティエディションを利用
  • Port関連のTypeScriptの型をelmで書けるちょっと嬉しいツール
  • elmとFirebaseを組み合わせたときのportが増えて面倒になってくる問題を解決するのにいい感じ
  • chokidarを使い自動で.elm-spa/defaultsに型情報を出力させるといい感じでelm-spaと連携できる
npx chokidar "src/InteropDefinitions.elm" --command "elm-ts-interop --output .elm-spa/defaults/Main.elm.d.ts"


elm-ui

  • 個人開発のお供
  • カジュアルにUIを作れるので重宝している
  • 毎回大体こんな感じのモジュールを作ってる


Cloudflare Pages

  • Netlifyは遅く、VercelはNext.js以外であまり恩恵を感じないためCloudflare Pagesを利用
  • 無制限商用利用可能で高速、CloudflareのWAF等と連携しやすいというメリットも感じる
  • デプロイ方法にリモートリポジトリ連携を選択した際にリポジトリを検索しにくいとうダッシュボードのUI的な問題を感じたが今回はGitlab CIからCLIでデプロイしているので特にデメリットを感じなかった


Gitlab&Gitlab CI

  • 普段Gitlabを個人開発に利用している流れで利用
  • Gitlabを個人開発に利用している理由はGitlab Pagesを利用すると簡単にアクセス制限をかけられるため。今回はCloudflare Pagesを利用しているのでGitlabやGitlab CIを使っている特別な理由は無い


Nix

  • 今回はfirebase-tools(Firebase Local Emulator Suite)をビルドして利用
  • firebase-toolsにJavaが必要なのでついでにNixで入れた、便利


Googleスプレッドシート

  • キャラ一覧データの作成に利用
  • スクリプト機能を使いJson出力した


Figma

  • ロゴ制作のために利用
  • UIデザインはしなかった


今回の開発の流れ

  • Figjamで雑に思考をまとめる

  • Excalidrawで雑にUIを考える

  • Figjamで雑にデータベースの設計

  • スプレッドシートでキャラ一覧データ作成

  • Notionのボードでタスク管理

  • 実際にコーディングしながら試行錯誤
  • Figmaでロゴだけ作成

課題

  • elm-uiでセレクトボックスを使うためにelm-input-extraのDropdownをWrapしたモジュールを作成したが文字列のみの扱いになってしまったので任意の型を扱えるようにしたい
  • ログイン後にロード中の画面が真っ白でフリーズしたと勘違いしてしまうため解決したい


今後のアップデートでやりたいこと

  • playrightでe2eテスト
  • SFVモジュール(ストリートファイターV用のモジュール)にDocテストを追加
  • ログイン後のロード中にアニメーションを追加したい


作った感想

  • elmとFirebaseを組み合わせた際のPortの多さから生じる面倒さをelm-ts-interopでいい感じに中和できた。elm-spa+elm-ts-interop+firebaseの組み合わせはelmで個人開発をするにはかなりありな選択肢だと感じた。
  • 速度だけならReactやChakraUIの方が出ると思うがテストコードを一切書かずにここまでリファクタしやすいのはelmならではのメリットだと感じた


©2021 yowanai.com