この記事は、現時点で自分がぼんやり考えていることをメモ代わりに書いたものです。
体系的な情報を求めている方には申し訳ありません。しかしだな、体系的に情報を整理しようとしたら、いつまでもアウトプットできないわけですよ。だから、たまにはこういう記事を。Qiitan、許して。でも今どき体系的な知識はAIで十分だろ?
CrystalはRubyコミュニティから派生したこともあり、Webアプリを作りたい人が多い。
しかし、プログラミング言語Crystalは「C言語にガーベジコレクションをつけてRuby風の文法を足したもの」と言えるもので、必ずしもWebアプリケーションに特化しているわけではない。
私はCrystalをコマンドラインツールやGUIアプリの開発に使いたいと思っていた。
ところが、どういうわけかCrystalでCLIツールを作りたいという人はあまり多くないらしく、ビルドや配布のエコシステムがいまひとつ整っていなかった。
それが欠点ではあったが、少しずつ問題を解決してきた結果、いまではだいたいほしいCLIツールはCrystalで作って配布できるようになったと思う。
一方でGUIに関しても、ライブラリが不足している。
もっとも、これはCrystalに限らず一般的な現象だ。GUIアプリというのは結局、プラットフォームが提供する不透明なAPIを利用せざるを得ないため、OSSとの相性があまり良くないのである。
それでも私は、libui-ng のRubyバインディングやCrystalバインディングを作成した。
結果として、libui-ng とガーベジコレクション言語との相性があまり良くないことがわかったが、それでも何とか使えるレベルにはできた。
次に気になったのが、TauriやElectronといったWebView系のアプリだった。
個人的にはJavaScriptをまともに読めないので全く興味がなかったのだが、最近の流行は無視できない。
CrystalにもWebViewのバインディングが存在する。
そして、冒頭で述べたようにWebアプリ開発は非常に活発だ。そこで私も試しに使ってみることにした。
調べてみると、WebViewというのはWindows・Linux・macOSそれぞれに別々のライブラリがあり、それらを webview/webviewプロジェクトやTauriのwryが統合しているらしい。Tauri自体はWebViewを提供しつつ、セキュリティの課題を解決するフレームワークのようだ。
CrystalでもTypeScriptなどを利用できるのかもしれないが、私はそれらが全くわからないので、個人的にkemal + ECR のような古典的なスタイルでやりたいと思っている。
実際にアプリを作ってみると、いくつかのことが分かった。
まず、イベントループやスレッド管理に注意が必要だ。
WebView自体が別プロセスで動作し、同時にKemalなどのサーバーも動かす必要があるため、マルチスレッド化して ExecutionContext を使い、適切にスレッドを割り当てないと動作しないことが多い。
また、ビルド・リンク・パッケージングが非常に面倒くさい。
ビルドについては、CrystalのWebViewプロジェクトにいくつかプルリクエストを送り、多少は改善できたものの、MinGWのビルドとか、なにをどうしたって辛い。MSVCについてはできないことはないが対応が面倒なので手を出さないことに決めている。共有ライブラリのバンドル作業も一筋縄ではいかない。なるべく静的リンクに寄せたいと考えるが、ライセンスの問題や、セキュリティアップデートのことを考えると、システムまたはアプリ付属の共有ライブラリにリンクしたほうがいいこともある。
ビルド・リンクを解決できたとしても、依然としてアプリケーションパッケージ、Appleディスクイメージ や、Inno Setup を用いたWindows向けインストーラや、debの作成は面倒だ。fpm などの便利なツールがあることを知れたのはよかったけど、結局はGitHub Action用のymlと、カスタムシェルスクリプトをAIに書いてもらうことになる。
完成したアプリはWindowsやmacOSの内蔵・外付けウイルス対策ソフトに誤検知される。
まあ仕事でやってる人なら、面倒のうちに入らないのかもしれないが、趣味でやっている人としてはとても面倒くさい。それでも、そうした面倒さを差し引いても実はかなりいい部分もあるんじゃないかと感じ始めている。