Biscuitというブラウザを趣味で開発していまして、先日1.0を無事リリースしました。Biscuitの開発の中で得た技術的な知見を何回かに分けて共有していきたいと思います。
Biscuitって?
複数のアプリをまとめて管理して利用できるブラウザです。Windows、Mac、Linuxに対応しています。同種のアプリとしてはStationやFranz、Ramboxなどがあります。
特徴は、アプリをグルーピングでき視認性が高い点と、アプリごとにクッキーやローカルストレージなどが隔離され、プライベートブラウジングと同じ状態になる点です。これにより、複数アカウントを同時に運用できます。また、アカウントが入れ替わってしまって誤爆したりするミスも起こりにくくなります。
その他の特徴はダウンロードサイトをごらんください。
プロトタイプフェーズ
最初、Electron上でVue.jsを使ってプロトタイプを作成しました。Vueを選んだのは以前から使い慣れていて、手早く実装ができるという理由からです。
プロトタイプフェーズの目的は、プロダクトのMVP(Minimum Viable Product: 最低限の価値を持った製品)の検証とMVPを実現性を担保するための技術検証でした。なのでMVPに関係のない新しい技術の導入はあえて我慢しました。ブラウザなのでどうしても新しい技術も触る必要がありますが、このフェーズでは最低限に抑えることができたと思います。
プロトタイプフェーズでは以下の点について検証しました。
- 便利なブラウザを作ることは可能なのか?
- 良いユーザー体験を実現できるか?
- 素早く動作するか?(できればChromeと遜色ないレベルで動作してほしい)
- 技術検証
- 複数のWebViewをタブで切り替えて動作可能か?
- それぞれのタブでセッション情報などを隔離可能か?
実際にプロトを作ってみて、上記の点について問題がないことがわかりました。プロトにかけたのは3日間ぐらいでした。作りながら、実際に自分で使ってみて「便利かどうか?」という点もドッグフーディングしていきました。
本実装フェーズ
プロトで有用性、実現性が確認できたので、本格的に開発することにしました。
本実装では React/Redux/Typescrptを使いました。凝り始めるとある程度の大きさのアプリになるのが予想できましたし、プロトで技術的な基本部分はクリアできていたので、新しい技術要素を入れてもいけるんじゃないかな?と思いました。結果、この判断は大正解でした。
- React → 複雑なビューの組み立てをコードで書ける。
- Redux → 状態管理をあまり考えなくてよくなる。全体アーキテクチャもレールに乗れる。
- Typescript → 静的型付けで開発効率が大幅に向上。安心してリファクタリングできる。
実際、この組み合わせで開発をおこなうようになってから、開発しやすく、メンテも楽な状態を保つことができるようになったと思います。(React/Reduxの部分はVue/Vuexなどでも問題ないと思いますが、今回はReact/Reduxを使いました)
Electronについて
ElectronはWebの技術でデスクトップアプリが作成できるツールです。Electronに関しては 公式ドキュメントがすごく充実しています。サンプルコードも多く、開発する上で困ることはあまりありませんでした。
ただ、ElectronはChrominumに基本的に依存しているため、開発中にElectronのバージョンアップに伴うバグが何点か発生しました。発見してものはGitHub上のElectronのプロジェクトにIssueとして登録しました。登録する際はElectronのIssueのポリシーに従い、
- OS
- Electronのバージョン
- 期待する動作
- 実際の動作
- 再現できるコードと再現手順
- 不具合を説明するためのスクリーンショットや動画
あたりをきちんと用意して登録しました。クリティカルなバグもいくつかあり、それらが修正されないとBiscuitがリリースできないため、丁寧ににIssueを登録しました。
中にはElectronの開発者の方の勘違いで、他のIssueとマージされて修正されないバグなどっもありましたが、適時コメントして再オープンしてもらって修正していただきました。このあたりはOSSといっても通常の開発と同じで「コミュニケーション重要」だと思います。
使用したElectron関連のライブラリ
Electron本体と関連する以下のライブラリを使いました。
"dependencies": {
...
"about-window": "^1.13.0", // Aboutダイアログ
"electron-context-menu": "^0.12.1", // コンテキストメニュー作成
"electron-dl": "^1.14.0", // ファイルダウンロードのヘルパ
"electron-find": "^1.0.5", // ブラウザ内でのキーワード検索
"electron-is-dev": "^1.1.0", // 開発モード判定
"electron-log": "^3.0.5", // ログ
"electron-squirrel-startup": "^1.0.0", // Windowsでアプリのデスクトップショートカットを作成
"electron-updater": "^4.0.6", // 自動更新
"electron-window-state": "^5.0.3", // Windowのサイズなどを保存
...
},
"devDependencies": {
...
"electron": "^6.0.0-beta.10", // Elecyron本体
"electron-builder": "^20.44.4", // パッケージング
"electron-notarize": "^0.1.1", // Macのアプリ認可自動化
"electron-reloader": "^0.3.0", // 開発時のオートリロード
...
}
それぞれのライブラリについては次回書きます。