はじめに こんにちは!Wantedlyでエンジニアをしています、山田です。Wantedlyのグループチャット機能 Sync の開発を担当しています。
ElectronはJavaScriptやHTML/CSSでデスクトップアプリが作成できると知られているOSSです。Node.jsとChromiumベースであり、 様々なプロジェクト で採用されています。大きなプロジェクトだとSlackやAtom、Visual Studio Codeなどが採用していますよね。WantedlyのグループチャットのSyncでもElectronを採用しており、macOS版 / Windows版両方のアプリケーションの配布をしています。この記事では、ElectronのAPI最前線について書いていきます。
macOS版 Sync
Windows版 Sync
ElectronはChromeベース 2016/08/22現在 、Electronはバージョン 1.3.3 がリリースされています。 7月25日にリリースされた1.3.0では、Node.jsのバージョン6.3.0を採用、Chrome52にアップグレードされました。これらのアップグレードで、ChromeやNode.jsのAPIが新しいものが利用できるのはとても嬉しいことです。また、Chromeの最新バージョンに追従してくれることで、Electronモジュールをアップデートすることでセキュリティやパフォーマンスの向上が見込めます。
Electron1.3以上で新しく加わった便利なAPI ここからは、Electronに最近追加されたAPIについて幾つか紹介していきます。
Trayアイコンのハイライト 以下のPul Requestで追加されました。
今までTrayアイコンのハイライトについてはクリックされた時にしかハイライトされず、クリックし終わるとハイライトは消えてしまっていました。しかしこのPull Requestでいつハイライトするかが選択できるようになりました。 例えば、以下のようなアプリをこのAPIを利用して簡単にハイライトできるようになりました。
これは新しく加わったAPIを利用して以下のように記述することで実現できます。
const tray = new Tray('/path/to/icon');
tray.window = new BrowserWindow({ ... });
// ...
tray.window.on('show', () => {
tray.setHighlightMode('always');
});
tray.window.on('hide', () => {
tray.setHighlightMode('never');
});
これで1passwordやdocker for MacなどmacOSの他のアプリに似た動きになると思います。細かいAPIですが、僕は好きです。
MenuItemでのズーム関連の設定 以下のPull Requestで追加されました。
ElectronにはmacOS / Windowsそれぞれのプラットフォームに向けたメニューを作成するAPIが存在します。しかしまだAPIが揃っているわけではなく、自分たちでメニューのラベルから、その項目を選択した時に動作する内容を自分たちで記述する必要がありました。バージョン1.3.2以前のElectronでは、メニューにおけるズームイン・ズームアウトの設定が大変になることが多いです。
例えばこのようなコードがあります。
Menu.buildFromTemplate([
{
label: 'View',
submenu: [
...,
{
label: 'Actual Size',
accelerator: 'CmdOrCtrl+0',
click: (item, focusedWindow) => {
if (focusedWindow) focusedWindow.webContents.setZoomLevel(0)
}
},
{
label: 'Zoom In',
accelerator: 'CmdOrCtrl+Plus',
click: (item, focusedWindow) => {
if (focusedWindow) {
const {webContents} = focusedWindow
webContents.getZoomLevel((zoomLevel) => {
webContents.setZoomLevel(zoomLevel + 0.5)
})
}
}
},
{
label: 'Zoom Out',
accelerator: 'CmdOrCtrl+-',
click: (item, focusedWindow) => {
if (focusedWindow) {
const {webContents} = focusedWindow
webContents.getZoomLevel((zoomLevel) => {
webContents.setZoomLevel(zoomLevel - 0.5)
})
}
}
},
]
},
...
]);
ただズームに関するメニューの設定だけで40行ほどあります。これで実現できるのは以下の3行になります。
このようなズームの他にもメニューの設定はあるはずなので、それらも同じように記述していくと、メニューの内容を記述するだけで100行は簡単に超えてしまうと思います。メンテナンス性を確保するためには冗長な部分はなるべく避けたいのが本心です。そこで、この追加されたAPIのおかげで、上記の長いコードが以下のようになります。
Menu.buildFromTemplate([
{
label: 'View',
submenu: [
...,
{
role: 'resetzoom'
},
{
role: 'zoomin'
},
{
role: 'zoomout'
},
]
},
...
]);
role が追加されたおかげで設定がこんなにも簡潔になりました。他のメニューのroleはAPIドキュメントに記載があるので参考にするともっと良いかもしれません。
どのように最新のAPIに追従していくか 僕自身の調べ方になりますが、まずElectronのリリースが載っているページをよく確認しています。
GitHubの electron/electron/releases と同じ内容になっているので、どちらでも良いと思います。Electronが独自に用意しているリリースのページではChangeLogが綺麗に載っているので確認しやすいと思います。また、Electronの場合はクロスプラットフォーム向けの変更か、macOS か Windows かで分けられています。そのおかげでどのプラットフォーム向けに対応すべき変更があるかがわかりやすくなっています。
Electronは1週間程度のサイクルで細かなリリースがされているので、追従していくにはこまめにElectronモジュールをアップグレードしていくことが重要です。Electronは小さなリリースでもセキュリティやパフォーマンスの改善がなされていますし、今回紹介したようなAPIなどもリリースされています。
実際、Electronが様々な開発者によって改善されていく中でよく変更される部分は、Electronを使ってアプリケーションを開発している人々からのフィードバックによって変わっているようです。常日頃利用されている、上記でもあげたメニューの role については新しい変更が次々と改善されているようです。
- Add zoomin, zoomout, resetzoom to MenuItem’s roles. #6777 - Add startspeaking and stopspeaking to MenuItem’s roles. #6765 - accelerator and label are now optional when role is specified for MenuItem. #6190 他にも、Visual Studio Code や Nylas N1 や Brave Browser などのOSSで且つ大きなプロジェクトとして動いているElectron製のアプリケーションを開発する人たちから、欲しい機能があるということで、Pull Requestを受け付けて他のOSSと一緒に改善をしているようです。
- https://github.com/electron/electron/pull/4181 - https://github.com/electron/electron/pull/6686 また、 Chromiumに追加された Chrome Web Push や Google に拡張機能として加わった Google Cast などのChrome自体の新しい機能を、なるべくElectronにも取り入れていこうという姿勢があるようです。OSSであるため、意欲的な開発者たちがIssue上で議論しているところが見受けられます。これらのAPIがElectronのプラットフォームで使えるようになると、より一層Electronを用いたアプリケーションの開発がなされるのではないでしょうか。
終わりに 日本でもいろいろな採用事例が増えてきていますので、最近はElectronを開発するのもそこまで敷居が高いものではなくなってきているのではないでしょうか。皆さんもWebの技術があれば簡単に導入できるElectronでデスクトップアプリを開発してみてください!