Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

同一アプリをWeb版とElectron版の両方で作る方法

皆さん、こんにちはmiyasakagoです。
この記事はNode.js_2 Advent Calendar 2018 - Qiitaの23日目です。

0)はじめに

ここ2年くらいで私自身、Electronを実案件の中で使う機会が増えているのですが、比較的遭遇するのは、同一アプリでWeb版もElectron版(デスクトップアプリ)も両方ほしい、というようなシチュエーションです。
f:id:acro-engineer:20181224200843p:plain:h250
例えば、Electronベースで開発されているアプリの一つにSlackがありますが、SlackはWebアプリとしてブラウザ上から利用することも、デスクトップアプリとして利用することも可能になっていますよね。

こういうことを実現したいと思ったとき、どういう方法があるのかいくつか選択肢があり、迷いました。
少し探してもあまり情報がなかったため、いろいろ調べ自分なりに整理してみました。

1)Webアプリを先に作り、Electron上からURL呼び出しする方法
2)Webアプリを先に作り、Electronに移植する方法
3)Electronアプリを先に作り、Webアプリに移植する方法

では、詳細を見ていきましょう。

1)Webアプリを先に作り、Electron上からURL呼び出しする方法

1. 概要

タイトルの通り、Webアプリを開発した後、そのWebページをElectronのウィンドウ上に読み込み動作させる、という方法です。

Electronには、外部のWebページを読み込み、デスクトップアプリ上で動作させる便利な機能があります。
その機能を活用した方法になります。(本機能の概要は後述します。)

2. メリット/デメリット

この方法であれば、WebアプリのソースコードをElectron側に移植するような作業は発生せず、開発はWebアプリ側に注力できます。
一方、制約も出てきます。以下に整理します。

  • メリット
    • 開発コストを抑えられ、納期も短くできる。
    • アプリのバージョンアップが楽。わざわざ更新プログラムを配信してインストールさせなくても、Webアプリを更新すれば、自動的にElectronアプリも更新される。
    • Web版、Electron版それぞれで、同じようなソースコードを2重管理する必要がない。
  • ・デメリット
    • インターネット環境での動作が前提になる。そのため、アプリの要件として許容できるかどうか、先に確認しておく必要がある。
    • Electronのネイティブアプリ用の機能(例:ローカルファイルへのアクセス等)の利用に制限が生まれる。

3. 実現方法

このブログでは、上記の実装方法の詳細までは解説しませんが、2つの代表的な方法の紹介だけ簡単にしておきます。

a. webviewを利用する
  • webviewは、外部のWebページを読み込み、Electronのアプリ上に表示する機能。
  • webviewタグの使い方はHTMLの標準タグであるiframeに似ている。
  • Electronのプロセスとwebviewに読み込んだWebページとの間で情報のやり取りが可能であったりと、iframeには無い便利な機能性を持っている。
  • 本格利用を考える場合、webviewはChroniumが維持管理をしている為、Electronの要望通りにバグ修正が進まないという課題がある。

webviewでできることや実装方法については、以下のページなどに詳しく書かれています。
qiita.com

b. BrowserViewを利用する
  • BrowserViewは、webviewに替わる方法として実装されたもの。
  • webviewと違い、BrowserViewはElectronが維持管理をしている為、バグ修正が進まないリスクを減らせる。
  • 一方、まだwebviewほど機能が充実していないので、その点を踏まえた選定が必要。

BrowserViewの基本的な使い方については、
今年のAdvent Calendarでも紹介されていますので、ここでは割愛します。
qiita.com

参考までに

現在のSlackのデスクトップアプリ(version3.0以降)は、BrowserViewを利用して実現されている代表例の一つです。
なお、Slackは、version2.xまではwebviewを用いており、3.0へのバージョンアップ時にBrowserViewに切り替えたことが、Charlie Hess氏の以下のブログで紹介されています。
slack.engineering

webviewとBrowserViewの選定をする上では、一度読んでおくことをおすすめします。

2)Webアプリを先に作り、Electronに移植する方法

1. 概要

「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」との違いは、Webアプリを作った後にソースコードをElectronに移植する点です。

f:id:acro-engineer:20181224194201p:plain:w500

移植を前提で考える場合、サーバサイドとクライアントサイドは疎結合にしておくことが重要であるため、SPA(シングルページアプリケーション)として開発しておくことをおすすめします。

また、サーバサイドをNode.jsで開発しておけば、ElectronのMainプロセスにサーバサイドのロジックも移植しやすくなるためおすすめです。
逆に、サーバサイドはAPIサーバとしてElectronには移植せず、Electronアプリから呼び出す構成にしても良いでしょう。

2. メリット/デメリット

  • メリット
    • 同じくWebアプリを先行開発する「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」に比べ、Electronアプリへの移植後に、Electronのネイティブアプリ用の機能を追加することが容易。
    • Webアプリ先行であるにも関わらず、移植した結果としてオフラインでも動作するデスクトップアプリを作ることが可能。(※ただし、クライアント-サーバ間の通信部分などは改修する必要がある)
  • デメリット
    • 同じくWebアプリを先行開発する「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」に比べ、移植のコストがかかる。
    • Web版とElectron版でソースコードが2重管理されることになるため、メンテナンスコストが高い。

3)Electronアプリを先に作り、Webアプリに移植する方法

1. 概要

「2)Webアプリを先に作り、Electronに移植する方法」の逆方向への移植を前提とした方法です。

f:id:acro-engineer:20181224194505p:plain:w500

前提として、ElectronアプリはNode.jsによって実行され(Mainプロセスと呼ばれる)、画面描画部分はHTML5、CSS3、JavaScriptによってChromium上で動作します(Rendererプロセスと呼ばれる)。
そのため、利用言語の関係上、ElectronアプリはWebアプリへの移植をしやすい構成になっていると言えます。

2. メリット/デメリット

  • メリット
    • Electronアプリを先に作るため、Electronのネイティブアプリ用の機能(例:ローカルファイルへのアクセス等)の利用に制約が生まれない。
    • そこまで意識せずとも、サーバサイドへの依存を減らした作りになりやすく、オフラインでも動作するデスクトップアプリを作りやすい。
  • デメリット
    • Electron上では、Mainプロセス(Node.jsで動作)とRendererプロセス(Chromium上で動作)はIPC(Inter-process Communication:プロセス間通信)による通信を行う為、その通信部分はそのままWebに移植はできない。
    • Electronのネイティブアプリ用の機能は移植できない為、Web移植時に交換しやすいクラス設計をしておくことが重要。
    • Web版とElectron版でソースコードが2重管理されることになるため、メンテナンスコストが高い。

4)まとめ

ここまで3つの方法を紹介しましたので、メリット/デメリットをまとめます。

No. 方法 メリット デメリット
1 Webアプリを先に作り、
Electron上からURL呼び出しする方法
・開発コストを抑えられ、納期も短くできる
・アプリのバージョンアップが楽
ソースコードの2重管理が不要
・デスクトップ版もインターネット環境での動作が前提になる
・ネイティブアプリ用の機能の利用に制限が生まれる
2 Webアプリを先に作り、
Electronに移植する方法
・ネイティブアプリ用の機能を追加することが容易
・オフラインでも動作するデスクトップアプリを作ることが可能
・1の方法に比べ、移植のコストがかかる
ソースコードが2重管理されることになる
3 Electronアプリを先に作り、
Webアプリに移植する方法
・ネイティブアプリ用の機能の利用に制約が生まれない
・オフラインでも動作するデスクトップアプリを作りやすい
・IPCによる通信部分はそのままWebに移植はできない
・ネイティブアプリ用の機能は移植できない
ソースコードが2重管理されることになる


最後に、上記のどの方法を採用するか決める上で、私が考えている判断基準を書いておきます。

  1. Webアプリ、デスクトップアプリのどちらをメインにするのか
  2. デスクトップアプリにてネイティブ機能の利用はどの程度求められるか
  3. 開発にコストと期間をどれだけ割り当てることができるか

これらの質問への回答とその優先度によって、採用する方法は概ね判断できると考えています。
例えば、分かりやすい例では以下のような具合です。

  • ネイティブ機能はあまり使う予定はなく、短期間での開発が求められる。
    →「1)Webアプリを先に作り、Electron上からURL呼び出しする方法」が良さそう
  • Webアプリメインだが、デスクトップアプリではネイティブ機能もしっかり使いたい。
    →「2)Webアプリを先に作り、Electronに移植する方法」が良さそう
  • デスクトップアプリがメインで、ネイティブ機能をしっかり使いたい。
    →「3)Electronアプリを先に作り、Webアプリに移植する方法」が良さそう

私のように「Webアプリもデスクトップアプリもほしい」というシチュエーションになったら、是非、参考にしてみてもらえたら幸いです。

それでは!

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
自社製品の開発から活用方法の提案まで関わりたいフロントエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com