イントロ

Webフロントエンドに特化したElmには、SPA構築をサポートしてくれるフレームワークelm-spaがあります。

2021-05に最新バージョンのv6がリリースされたので、v5で構築中だったSPAをv6へバージョンアップしてみました。

前提

elm-spaの公式ガイドを見た限りでは、かなり大きな変更が入っているようです。

  • CLI
  • ルーティング
  • ページ追加
  • 認証関連

v5で作成しているコード量が少なければスクラップ&ビルドで作り直すという選択肢もありましたが、 それなりのコード量になっていたため、まずはv5のコードベースをそのままv6へ移行できるか検証してみました。

rm -rf node_modules
grep elm-spa package.json  #=> "elm-spa": "^6.0.0",
npm install

v6のインストールは問題なく完了したので、CLIでローカル起動させてみます。

v5ではnpm scriptsに様々なコマンドを設定してくれていましたが、v6では npx elm-spa server が起動コマンドになるようです。

何の問題もなく起動し、アプリケーションの挙動も従来どおりなので無事完了したかと思いきや、確認していくとどうやらこれではダメなようです。

要因

elm-spaのv6では、v5に存在しなかった .elm-spa というディレクトリが生成され、ここにSPA関連のベースロジックが配置されます。 このディレクトリはgitの管理対象外とする必要があり、v6でプロジェクトを生成した場合は elm.json にも以下の記述が存在します。

{
  "source-directories": [
    "src",
      ".elm-spa/defaults",
      ".elm-spa/generated"
  ],
}

.elm-spa/defaults にはエントリポイントとなる Main.elm が存在し、この設定があることで 関連ロジックを利用してElmアプリケーションをビルドしてくれるようです。 v5ではディレクトリ直下に存在した Spa モジュールの代替といったところでしょうか。

上記の手順ではプロジェクトの初期化を行っていないため、元々存在した Main.elm ベースでビルドされてしまい、 elm-spa のバージョンが上がっただけでビルドはv5そのものだったようです。

移行

プロジェクトを新しく生成

v6であらたにプロジェクトを生成するのが良さそうなので、既存のElmファイルはいったんすべて退避し、 あらためてプロジェクトを生成していきます。

v5でプロジェクトを生成する場合は、gitリポジトリ直下に指定したディレクトリ名でプロジェクトが 生成されていましたが、v6ではカレントディレクトリに必要な一式を生成してくれます。

ビルド

プロジェクトが生成されたら npx elm-spa server でローカル起動させます。 v5ではポート番号が8000番でしたが、v6では1234番に変更されています。

http://localhost:1234 へアクセスし、elm-spaが生成したデフォルトのページが表示されていることを確認できました。 ここから、退避していたv5のコードをあてていきます。

ポイント

ベースロジックの格納場所変更以外にも、バージョンアップにより幾つかの変更が入っていました。

  • ビルド成果物のファイル名
    • JavaScriptのファイル名は elm.compiled.js から elm.js に変更されています
  • npm scripts
    • 一切追加されません
    • npm scriptsで行っていたものはすべて、elm-spaのサブコマンドで代替できるようです

v5のコードを配置

元々、コードベースはある程度大きくなることが分かっていたので、v5で生成されるページ用モジュールから アプリケーション独自の型は独立させていました。そのため、これらの型はv6ベースのプロジェクトに持ってきても 問題なく動作しました。

懸念点はv5のページ用モジュールですが、これはやはりそのまま持ってくるだけだと軒並みコンパイルエラーになりました。

ただ、Elmコンパイラのエラーメッセージは非常に親切なので、いつものElmアプリケーション同様に指摘された箇所を 淡々と修正していけば、問題なく動作するようになりました。

v6の嬉しいところ

すべての機能を利用しているわけではないですが、既に述べている点も含めていくつか嬉しい点がありました。

プロジェクトの初期化方法

指定したディレクトリ下にプロジェクトが生成するのではなく、カレントディレクトリに生成されるよう変更されています。 v5ではカレントディレクトリを指定することができず、初期化後にファイルを移動していたので、地味に嬉しい改善です。

カスタマイズの方法

v5では Spa ディレクトリに自動生成されるコードが配置されますが、v6では .elm-spa がそれにあたります。 これらのコードはページの追加などによりelm-spaが自動で書き換えていくため、バージョン管理すべきかどうか、 あるいはこのコードに手を入れたい場合はどうすれば良いか?という点が悩みどころでした。

v6では、(.elm-spa/defaultsに限ってですが)カスタマイズしたい場合は該当ファイルを src 直下に移動すれば良い、 と明記してくれているので、判断に迷うことが無くなりました。

認証制御の方法

v5では、SPA側で認証に関するハンドリングを行いたい場合の方法をガイドに記載してくれていましたが、 あくまで自分で機能を拡張するイメージでした。

v6にはこれらの機能が内包されたようで、機能を利用する方法もガイドに丁寧にまとまっています。

まとめ

elm-spa をv5からv6にバージョンアップしました。

v5の既存コードベースをいったん退避してv6でプロジェクトを再作成し、そこにv5の既存コードを載せていくアプローチです。 Elmそのもののシンプルさとコンパイラの親切さに助けられ、当初想定していたよりもスムーズに最新バージョンへ追随できました。

なお、v6のリリースにあわせて公式ガイドも刷新されており、v5のガイドを単純に参照することはできないため、 よほどの理由が無い限り、バージョンアップしてしまうのが今後のためにも良さそうです。