C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

reddit で話題になった Tauri と NEON についてのメモ、ついでに template-rust-backend-with-electron-frontend の開発理由についてのメモ

reddit の Rust コミュニティーtemplate-rust-backend-with-electron-frontend のリリースについてポストしたところ、主に2つ、 Tauri と NEON について話題になりました。( up-vote たくさんとちょうど使いたかったんだありがとう的なポストも頂きました。幸いです。 )

1. Tauri vs. Electron ( 間接的には template-rust-backend-with-electron-frontend にも関連します )

こちらは template-rust-backend-with-electron-frontend にとっては via via 的な間接的でややオフトピックよりな感じの内容ではありますが、特徴的な部分についての対決姿勢的な議論が生じていました。主な主張は次の2通り(意訳と補足を含みます):

  1. Tauri 上げ上げ系
    • Tauri なら高速でフットプリントも高々6MBに収まるよ、 Electron はすごい重いっす😭
  2. Tauri じゃない理由を推論してくれる系
    • Tauri のフットプリントが小さいのはブラウザーがバンドルされておらず、OS が提供するブラウザーを WebView として使うから。つまり…
      • 動作や見た目が実行環境によって変わる可能性(ブラウザーの種類やバージョンによる互換性問題)をアプリ側で考慮する必要が生じる
        • Electron だと WebView をバンドルする特定版の Chromium に決め打ちできる (少なくともユーザー環境に依存したブラウザーの互換性問題は起こらない)
        • 実際問題: OSX -> Safari が起動、 WindowsMSHTML が起動するとつらい😭 (まともに更新されている一般的なWindows 10しか考慮しなくていい世界ならEdgeだけどね😜)
    • Tauri はまだ若く TODO な部分がまだたくさんあるんだ

vs. な姿勢については、 Rust バックエンドに Web 系テクノロジーのフロントエンドをマーシャリングする選択肢について「でも、現時点の選択肢としては両方からどちらもかんたんに選べるのが嬉しいじゃろ」と思います。 Tauri が順調に TODO を消化し、その上でさらにビルド・プロセスで特定のブラウザーをバンドルする能力を獲得する日が来たら、 Tauri は Electron に対してほとんど上位互換的な技術要素になり得ますが、 TODO 消化はともかくバンドル能力の獲得は恐らく Tauri の開発思想的に無さそうな気はします。

Tauri は Rust のフロントエンド向け技術要素として現状に対しては良い選択肢の1つだと思います。名前が STARGATE の地球の人の意味の Tau'ri っぽいのも面白い点です。しかし、ブラウザー互換性問題への対処可能性がアプリ開発のプロジェクトチームの負担となる事は、特に「日本企業」とか「役所」とか「瑕疵担保」などを考える場合には2020年現在もまだネガティブな要因として考慮から外せないかなって思います。そうした懸念の低い分野のプロジェクトでは積極的に採用しても面白いのかな、と思います。

また、 Tauri の公式 README.md を見る分には TODO もそれほど困るコア機能的な部分は既に無さそうには見えます(どう見ても OSX 好きな開発者が中心になっているので WindowsGNU/Linux ではうまく動かない機能とかある"かも")。 Tauri vs. Electron については reddit で生じていた議論も核心の1つではありますが、 Tauri 公式の README.md の Comparison between Tauri and Electron が網羅的でわかりやすい1つ比較例として有用そうです:

参考: https://github.com/tauri-apps/tauri

  1. フットプリント: 例えるなら、
    • Electron はスイス・アーミー・ナイフ、
    • Tauri は刃先は現地で調達した何かを挿して使えるナイフの柄みたいなものかなーと思うので、「Tauri、せやろな」と素直に思います
  2. Interface Service Provider:
    • 多様性とユーザーへ選択肢を与える事は思想的にも、もしもの「こんなこともあろうかと」への備えとしては理想性が高いけれど、
      • 現実は reddit でも議論になったように可能性があるだけでもしんどい上に実際にもブラウザー互換性問題はしんどい部分がまだ捨てきれません
    • 開発チームの現実の負荷と生産性へのデメリットの視点からは Tauri は不利に思います
  3. Backend Binding:
    • Tauri vs. template-rust-backend-with-electron-frontend ではどちらも Rust になるし、
      • どちらもネイティブなバイトコードが実行されるので差はないですね
  4. FLOSS:
    • Electron も現実的に問題になる可能性は既に極めて低いので、
    • あとは宗教的/政治的な意図で Free/Libre 互換性を気にしたいかどうか次第じゃないかな
  5. Multithreading:
    • Tauri が Yes と堂々と書いていてつよいなーとは思います。技術変態的な用途で遊びたいなら Tauri が楽しいかもしれません。
    • ただ、実用性としてはそもそもデスクトップアプリのフロントエンド部分としての Electron について、 ES の Worker、そもそもの ES の実行効率、また Tauri が堂々と Yes と言うからにはそこにはブラウザー互換性とそれをカバーするであろうサブシステムもあるのでしょうし、遊びかなーって思います。
    • バックエンド部分を分離したアーキテクチャーでフロントエンド部分で MT が活きる用途というのは実際には非常に限られます。もしレンダリングをMT化できれば嬉しいのでは、と思う人もいるかもしれませんが、OSの描画コンテキストを生で扱える処理系でもレンダリングのMT化はまだまだ極めて困難な技術です。仮にGLコンテキストを使うならWindowsではGLコンテキストのMT対応は不十分ですし、そもそもプラットフォーム依存という仕様で困難が大きいです。加えて、ブラウザーで標準化された Web Worker (厳密にはこれはJavaScriptECMAScriptの仕様ではなくブラウザー側で追加されるWeb APIに含まれる仕様です)は MT としてはメッセージングベースで…閑話休題
  6. Auto Updater:
    • Electron にはあります。製品の要求にこの機能が欲しい事はしばしばあるので便利です
    • Tauri も Soon らしいので期待したいですね。
  7. Android, iOS:
    • Electron の弱点の1つかもしれません
    • この点は「 Tauri なら」と言える強みかもしれません
  8. No localhost option:
    • Electron の実行環境がマルチユーザーなシステムの場合にファイアーウォールを比較的高度に設定できないと脆弱性になり得えます
    • この点も「 Tauri なら」と言えそうです
      • もし開発するアプリのリリースターゲットがマルチユーザー同時ログオンを考慮する必要があって、その上でリッチなGUIデスクトップアプリを実行させたいなら、というニッチな状況も想定しなければならないなら、だけど
  9. Desktop Tray:
    • Tauri では Soon
    • Electron では No
      • native バックエンドを持つアプリなら必要に応じてトレイ常駐的な機能の後付けはどうとでもならない事もない
      • プロセス内から実現しにくい場合はトレイ用の別プロセスを立ててIPCすればそれほど難しい機能ではありません (クロスプラットフォーム対応したいとなると少々しんどくなります)

以上の比較表の外で Tauri の TODO から気になるのは Multiwindow Mode です。「にゃんにゃんしますか?(でんっ)」みたいなダイアログも原理的にはマルチウィンドウなのだけど、そういう部分なのか、また少し違ったニュアンスなのかは調査してみないとわかりませんが、チョット気になります。

(1と2のハザマ): template-rust-backend-with-electron-frontend の開発理由

私が template-rust-backend-with-electron-frontend を準備したモチベーションはそもそも…

  • WebView 系フロントエンド技術要素の開発
  • Electron や関連プロジェクトへのコミット
  • Tauri や関連プロジェクトへのコミット
  • FLOSS の普及/布教または単にボランティア・ハートによる奉仕したみ
  • Rust バックエンドに対応する GUI Toolkit の開発
  • 何であれとにかく GUI Toolkit 的なフロントエンド技術の開発

ではなく、寧ろそのようなあたりへ触れている人生の資源の余裕は残念ながら無いので、

  • Rust でアプリ作りたいけど
  • GUI Toolkit 的なフロントエンド技術の成熟がまだ弱い
    • Qt や Gtkバインディングはあるけど高価 or Free/Libre なライセンス汚染が生じてしまう ( OSS 作りたいだけならいいんだけど… )
    • conrod だとビジネス的なGUI部品やデフォルトでの見栄え的に弱い (日本語の入出力ちゃんとできてすごいし、ゲーム開発ならGUI部品も絵作りから独自にやりたいからその用途で使うなら問題にならないんじゃが…)
    • OrbTkdruid にも期待したいけど、"今"使うには若すぎる…せめて日本語の入出力…ウィジェット(≃コントロール)もモウチョット欲しい… (作ったりミコットしたりしつつ、それを使った製品本体も作る余力はない用途にも使いたいんじゃ…スマヌ…)
  • どうせ "今を凌ぐ仮のフロントエンド技術" を採用するなら…
    • できるだけバックエンドとは疎結合ですげ替えやすさを維持できる要素技術だと嬉しい
    • あれがない、これはできない、それは作らないといけない…そうした事ができるだけ少ない成熟した技術をぽんっと使っておきたい
      • (=プロジェクトチームの生産性を "仮のフロントエンド" にできるだけ注ぐ必要が少ないと嬉しい)
    • ルック&フィール、意匠設計的な部分に手を付けるのにフレームワークの深い理解が必要ない方が嬉しい
      • ("顧客が本当に必要だったGUI" への要求に手早く簡潔に対応できるものだとなお嬉しい)
    • 表示とUIとしての入出力部分だけきちんとうまいことやって貰えたら、あとはバックエンドの開発力でどうとでもするぞい💪💪💪

と、いうわけで、そういう事なら…

  • .NET Core/WPF/Prism
  • Node.js/(...brabrabra...)/React/Electron

どっちかが私や関連するプロジェクトチームのスキルセット的にも有利な選択肢ネ、でも Rust 純度高い技術の可能性も捨てたくは…やっぱり少なくとも今はまだダメでした…となった流れと、 .NET Core の WPF だと Windows 以外へのクロスプラットフォーム・ポータビリティー的に不安しかない、 Node.js/React/Electron 系を採用しておけばバックエンド Rust と融合させて Windows, OSX, GNU/Linux での心配は少ないし、チョットどうにかすれば Web サービス、さらにモウチョットどうにかすれば Android / iOS 向けにも fork しやすい…ハズ…。

と、いうことでにゃんにゃんしてできたのが template-rust-backend-with-electron-frontend です。要素技術のシンプルなマーシャリングを実現しただけの状態のプロジェクトテンプレートはバックエンドプロジェクトに余計な束縛を与えない事も大事な要素です。もちろん、ある程度はアレ向け、ソレ向け、と用途にフォーカスした派生プロジェクトテンプレートも用意したいとは考えていますし、できれば Rust cdylib と Electron の間のマーシャリング・コードの自動生成機能を付けたい気持ちもあります。但し、しつこいようですが、バックエンドの Rust コードが主体で、その開発に制約を設けたり、特定のツールやビルド方法への強めの束縛は取り込みたくありません。

2. NEON; Rust と Node.js を繋ぐマーシャリング技術

NEON 自体は Rust と Node.js のマーシャリング技術要素部分に注力した「補助的なビルドツール」のプロジェクトです。

実用していなかったので単純に存在を忘れていました、という正直なところはあるのですが、 reddit で「どうして NEON 使わないんだい?」的な議論から試みました。いい感じに template-rust-backend-with-electron-frontend へ組み込めたら素直に嬉しい技術です。

Windows で試したところ、開発環境への NEON ツール群の導入は簡単にできたものの、プロジェクトテンプレートを作成するコマンドライン・インターフェースが挙動不審で制御が帰ってこなくなりました😭

誰も助けてくれない気配を感じたので NEON の repos を git clone して NEONcli 部分についてコードを確認、 TypeScript と判明したのでデバッガー(今回は VSCode を使いました)に必要な設定の変更と追加をして適当にブレークポイントを挿しつつステップ実行してみました: -> https://github.com/neon-bindings/neon/issues/406#issuecomment-601832883

結果: console.log() で制御が行方不明になる -> https://github.com/neon-bindings/neon/issues/406#issuecomment-601832883

原因がわかればもちろん修正して PR したいところでしたが、わたしの Node.js / TypeScript のワカリでは状況に対して修正すべき原因に適切な直感が綺麗には働きませんでした。残念。

ただ、不幸中の幸い、この問題はどうやら neon new の主だった処理を終えた後、残すところフレーバー的な表示の出力だけになった状態で発生する、実質的にはそれがわかっていれば実害は無い部分という事もわかりました。WSL2 を使えば Windows と共有するファイルシステム上にも neon new 期待動作できる事は先の Issue #406 へのレポートのようにわかっていましたし、さいあく neon new できなくても neon build --release できるプロジェクトをどうにかできれば NEON 自体は WSL2 も使えない Windows 開発環境のメンバーがプロジェクトチームに居たとしても大丈夫…かも…などなどありましたが、その前提の "さいあく" はとりあえず回避できました。

  • neon build --release

これで "Hello, world" 的な .js は出力できました。build では new のような問題が起こらなくて一安心です。続いて、NEON 公式の docs の確認を進めると、

を見つけました。「ぉ、これはオレオレテンプレートからもりもりしたり、 neon new から Electron/React/その他いっぱいのプロジェクト初期状態の構築や依存関係のうにゃーとかせずに使えて便利になるのかも?」とちょっと期待しました。

ダメでした…。よく見ると neon-hello は4年も保守されていません。 昨年あったらしい PR #1 にも Author の応答が無さそうです。お手軽にはじめるテンプレート・プロジェクト的な部分だと思うので、手動でどうにかすればいいのかも、とも思いますが…

  1. 少なくとも "いま" フロントエンド部分の要素技術に手間暇を割きたくはありません ( 趣味のOSS開発&コミット活動としてなら何であれ参加できるのはたのしーのだけど… )
  2. neon build --release しかできない束縛ちょっと嫌かなぁ…
    • たぶん NEON ではマーシャリング部分のみ neon して、結果的には3層構造の Node.js 処理系 <--> neon した .rs から .js と cdylib のマーシャリング部分 <--> .rs pure な rlib なアーキテクチャーを前提にしているのかなーと思うので、そのために --release しか受け取らないのかなーとは感じるものの

加えて、NEON本体のソースについても要素技術の更新がかなーーり古いまま保守されていない部分もあり、「うーむ、これなら… template-rust-backend-with-electron-frontend にマーシャリング・コードの自動生成機能を cargo か npm / yarn のカスタムビルドでオレオレ機能追加した方がいいかなぁ…というお気持ちも。 NEON と良し悪しで戦う気はありませんが、アプローチの思想的にも、アーキテクチャー的にも差異を感じつつ、もう少し NEON については試しておこうかな…といった具合です。いまのところ。