Electron.jsを使用する前に知っておきたいこと

この記事では、Electron.jsについて学ぶときに私が犯した間違いのいくつかを回避する方法を共有しますか?‍♂️。お役に立てば幸いです。

:これはコーディングのチュートリアルではなく、私の個人的なポイントについてのディスカッションです。

数か月前、私は副産物であるtaggrの構築にもっと集中することにしました。コンピューターにたくさんの写真があるので、それを作成するように促されました。

写真のバックアップを保持している私たちにとって、これらのコレクションは非常に大きく複雑になることが多く、管理するフルタイムの仕事になります。フォルダーとサブフォルダーの組み合わせには、インスタントメッセージング画像のバックアップ、バリ島への旅行、叔父の結婚式、または昨年の独身最後のパーティーからの高解像度画像が含まれる場合があります。

そのようなコレクションを常に整頓するのは面倒です(私を信じてください、私は何年も試してきました)。それも難しいフォルダーの奥深くに隠された、あなたが最も愛するショットを発見するために。

だからtaggrその問題を解決するデスクトップアプリです。これにより、ユーザーはプライバシーを守りながら思い出を再発見できます。

私はクロスプラットフォームのデスクトップアプリケーションとしてtaggrを構築しています。ここでは、Electron.jsを使用したクロスプラットフォームアプリ開発について学んだことのいくつかを、最初から知っていればよかったと思います。始めましょう!

バックグラウンド

Electronとのこの進行中の旅についての私の持ち帰りを紹介する前に、私自身とtaggrの要件についてもう少し背景を説明したいと思います。

開発者はそれぞれ異なるバックグラウンドを持っており、開発するアプリケーションの要件も異なります。

このプロジェクトのために私が行った選択をコンテキスト化することで、将来の開発者がニーズと専門知識に基づいて適切なツールを選択できるようになる可能性があります(GitHub ?、私はあなたを見ています)。

前述のように、私は最初からtaggrをクロスプラットフォームアプリケーションとして想定してました。このアプリは、プライバシーに重点を置いているため、クライアント側で必要なすべての前処理と機械学習の計算を実行します。

一人のショーとして、私は自分のアプリを一度書いて、正気を失うことなく別のシステムに出荷できるようにしたかったのです。

私の側から見ると、私はWebとJavaScriptが大好きなフロントエンドエンジニアです。以前はJavaとC#を使用していましたが、Webが提供する柔軟性とその活気に満ちたエコシステムを楽しんでいます。

以前にEclipseRCPなどのツールを使用してクライアント側アプリを構築することの苦痛を直接経験したことがあるので、その技術を再び使用したくないことはわかっていました。

要するに、taggrのスタック要件は次のように要約されます。

  • 理想的にはフレームワークレベルで、クロスプラットフォームサポートを提供する必要があります。?
  • これにより、コードを1回記述し、必要に応じてプラットフォームごとに微調整できるようになります。?️
  • 特定のランタイムをインストールしなくても、ホスト環境に関係なく、機械学習機能にアクセスできるようにする必要があります。セットアップするのは簡単なはずです。?
  • 可能であれば、Webテクノロジー使用する必要があります。私の既存の知識を活用するのは素晴らしいことです。?

ご覧のとおり、要件は次のようには読めません。ReactwithRedux、observables、およびWebSocketを使用する必要があります。これらは低レベルの実装の詳細であり、必要が生じた場合いつ、必要に応じて決定する必要があります。

手元の問題を無視して、最初からスタックを選択するのではなく、ジョブに適したツールを選択してください。

それで、猛烈なグーグルの後、私はエレクトロンを試してみることにしました。私は以前にそのフレームワークを使用したことがありませんでしたが、多くの企業がAtom、VS Code、Discord、Signal、Slackなどの製品でこのフレームワークをうまく使用していることを知っていました。

オープンソースであり、JSエコシステムとNodeエコシステムの両方とすぐに互換性があり(ElectronはChromiumとNodeを使用して構築されています)、Electron.jsは手元の作業にとって魅力的なツールでした。

必要に応じてコアパーツ(永続性レイヤーとビューレイヤー)を繰り返し変更したため、スタックの残りの部分についてはあまり詳しく説明しません。これはこの記事の範囲外です。

ただし、ホストにMLの特定のランタイムをインストールせずに、トレーニングの実行とMLモデルのブラウザー(WebGLを使用)およびノー​​ド(Cバインディングを使用)での直接展開を可能にするTensorflow.jsについて説明します。

さて、Electronに戻りましょう。完璧だと思って、楽しみが始まりました。??

背景について十分に話します。持ち帰りに飛び込みましょう。

1.小さく(そしてゆっくり)始めますか?

これは新しい概念ではありませんが、定期的に取り上げる価値があります。Electronを使用できる素晴らしいスタータープロジェクトがたくさんあるからといって、すぐに1つ選ぶ必要があるわけではありません。

待つ。何?

遅いのはスムーズで、スムーズは速いです。—海軍のことわざ

利便性には複雑さが伴います

これらのスターターには多くの便利な統合(Webpack、Babel、Vue、React、Angular、Express、Jest、Redux)が含まれていますが、問題もあります。

Electronの初心者として、私は「Electronアプリの作成、公開、インストール」の基本を追加のベルやホイッスルなしで含む無駄のないテンプレートを選ぶことにしました。最初はWebpackでさえありませんでした。

すぐに立ち上げて実行するには、electron-forgeに似たものから始めることをお勧めします。Electronのロープを学ぶために、依存関係のグラフと構造を上に設定します。

問題が発生した場合(そして問題が発生した場合)、最初に+30 npmスクリプトと+180依存関係を持つプロジェクトを選択するよりも、カスタムスタータープロジェクトをビルドした方がよいでしょう。

とは言うものの、Electronの基本に慣れたら、Webpack / React / Redux / TheNextHotFrameworkでゲームを自由にステップアップしてください。私はそれを段階的にそして必要なときに行いました。どこかでクールな記事を読んだからといって、todoアプリにリアルタイムデータベースを追加しないでください。

2.アプリを慎重に構成しますか?‍♂️

これは私が認めるよりも少し時間がかかりました。?

最初は、UIとバックエンドコード(ファイルアクセス、拡張CPU操作)を混同したくなるかもしれませんが、物事は非常に速く複雑になります。私のアプリケーションの機能、サイズ、複雑さが増すにつれて、1つの絡み合ったUI +バックエンドコードベースを維持することはより複雑になり、エラーが発生しやすくなりました。また、カップリングにより、各部品を個別にテストすることが困難になりました。

埋め込みWebページ(DBアクセス、ファイルアクセス、集中的なCPUタスクなど)以上のことを行うデスクトップアプリを構築する場合は、アプリをモジュールにスライスして結合を減らすことをお勧めします。単体テストは簡単になり、モジュール間の統合テストへの明確な道があります。taggrについてはここで提案されている構造に大まかに従いました。

その上、パフォーマンスがあります。この問題に関する要件とユーザーの期待は、構築しているアプリケーションによって大きく異なる場合があります。しかし、高価な呼び出しでメインスレッドまたはレンダリングスレッドをブロックすることは決して良い考えではありません。

3.ねじ切りモデルを念頭に置いて設計しますか?

ここではあまり詳しく説明しません。主に、公式ドキュメントで見事に説明されている内容を2倍にしています。

taggrの特定のケースでは、長時間実行されるCPU、GPU、およびIOを集中的に使用する操作が多数あります。Electronのメインスレッドまたはレンダラースレッドでこれらの操作を実行すると、FPSカウントが60から低下し、UIが遅く感じられます。

Electronは、WebWorkers、Node Worker Threads、BrowserWindowインスタンスなど、メインスレッドとレンダラースレッドからこれらの操作オフロードするためのいくつかの代替手段を提供します。それぞれに利点と注意点があり、直面するユースケースによって、どちらが最適かが決まります。

メインスレッドとレンダラースレッドから操作をオフロードするために選択する選択肢に関係なく(必要な場合)、通信インターフェイスがどのようになるかを検討してください。アプリケーションの構造と機能に大きな影響を与えるため、満足のいくインターフェースを思いつくのに少し時間がかかりました。アプローチを選択する前に、さまざまなアプローチを試してみると役に立ちました。

たとえば、WebWorkersのメッセージパッシングインターフェイスをデバッグするのが最も簡単ではないと思われる場合は、comlinkを試してみてください。

4.テスト❌、テスト❌、およびテスト✔️

古いニュースでしょ?私が最近直面したいくつかの逸話的な「問題」のために、これを最後のポイントとして追加したいと思いました。1番目と2番目のポイントに強く関連しており、カスタムスタータープロジェクトを構築し、早い段階でミスを犯すと、開発の貴重なデバッグ時間をさらに節約できます。

アプリのUIとバックエンドを2つの間のクリーンなインターフェースを備えたモジュールに分割するという私の推奨事項に従った場合、自動化されたユニットテストと統合テストのセットアップは簡単です。アプリケーションが成熟するにつれて、e2eテストのサポートも追加することをお勧めします。

GPS位置抽出?️

2日前、taggrのGPS位置抽出機能を実装しているときに単体テストが緑色になり、機能が開発(Webpackを使用)で機能するようになったら、実稼働環境で試してみることにしました。

この機能は開発ではうまく機能しましたが、本番環境では惨めに失敗しました。写真のEXIF情報はバイナリとして読み取られ、サードパーティのライブラリによって処理されました。バイナリ情報は両方の環境で正しくロードされましたが(diffでチェック)、本番ビルドでそのようなデータを解析するときにサードパーティライブラリが失敗しました。すみません、 ??

解決策:Webpackによって設定された開発環境と本番環境のエンコード設定が同じではないことがわかりました。これにより、バイナリデータは開発中はUTF-8として解析されましたが、本番環境では解析されませんでした。この問題は、ElectronによってロードされたHTMLファイルに適切なエンコーディングヘッダーを設定することで修正されました。

ファンキーな写真?

画像を操作して操作するとき、JPEGがコンピュータ上で「正しく機能する」場合、それは有効なJPEGであると考えるかもしれません。間違っています。

Node画像処理ライブラリをシャープに操作しているときに、一部のJPEG画像のサイズを変更するとアプリがクラッシュしました。よく調べたところ、原因はSamsungファームウェアによって生成された誤ったJPEG画像でした。?‍♂️

解決策:アプリで改善されたエラー境界を設定し(例:try-catchブロック)、JPEG解析モジュールを微調整し、すべての疑いがあります。?️

概要

ノードとJavaScriptのエコシステムは開花しており、多くの強力なツールが毎日作成され、共有されています。

オプションの数が多いため、新しい素晴らしいElectronアプリの構築を開始するための明確なパスを選択するのは困難です。選択したフレームワークに関係なく、次のことに焦点を当てることをお勧めします。

  1. 小さく始めて、徐々に複雑さを加えていきます。
  2. アプリを慎重に構成し、バックエンドを維持し、UIの問題をモジュール化します。
  3. 小さなアプリを作成する場合でも、スレッドモデルを念頭に置いて設計してください
  4. テストと再テストを行って、エラーのほとんどを早期にキャッチし、頭痛の種を減らします。

最後まで頑張ってくれてありがとう!?

taggrは、ユーザーがプライバシーを維持しながらデジタルメモリ再発見できるようにするクロスプラットフォームのデスクトップアプリケーションです。Open-alphaは、Linux、Windows、およびMacOSでまもなく登場します。ですから、TwitterとInstagramに注目してください。ここでは、開発の更新、今後の機能、ニュースを投稿しています。