Electron を試す 5 - Electron v0.35.0 対応
Electron v0.35.0 で互換に影響のある変更が入ったため、その対応についてまとめる。既に v0.35.1 もリリースされているけれど、こちらは大きな変更がないため今回は取り扱わない。
v0.35.0 Release Notes
まずは Electron v0.35.0 の Release Notes を確認。
ざっくり意訳。
共通
- Show warnings for deprecated APIs, can be turned off with
process.noDeprecation
.- 非推奨の API に対して警告を表示するようにした
- この警告を無効化する場合は
process.noDeprecation
を指定すること
- Add
electron
module which includes all public APIs.electron
モジュールを追加して public な API はそこへ含めるようにした
- The
ipc
module is deprecated, should useipcRenderer
in renderer process, andipcMain
in main process.ipc
モジュールを非推奨にした- かわりに Renderer プロセスでは
ipcRenderer
、Main プロセスはipcMain
を使用すること
- The
ipcRenderer
module adds anevent
object when emitting events, to match the style ofipcMain
module.ipcRenderer
のイベント ハンドラーにevent
オブジェクトを追加した- この対応により
ipcMain
と設計 ( インターフェース ) が等しくなる
- Remove the
-
inBrowserWindow
's option names.BrowserWindow
のオプション名から-
を削除した
clicked
events inTray
are renamed toclick
.Tray
イベントのclicked
をclick
に名称変更した
- The
Url
in API names is replaced withURL
.- API 名の
Url
という表記をURL
に置き換えた
- API 名の
- Add
documents
,downloads
,music
,pictures
,videos
keys toapp.getPath
.app.getPath
のキーにdocuments
、downloads
、music
、pictures
、videos
を追加
- Fix memory leak of
webContents.beginFrameSubscription
.webContents.beginFrameSubscription
のメモリー リークを修正した
Windows
- Add support for toast notifications on Windows >= 8.
- Windows 8 以降のトースト通知に対応した
OS X
- Add
drag-enter
,drag-leave
,drag-end
anddrop
events toTray
module.Tray
モジュールのイベントにdrag-enter
、drag-leave
、drag-end
、drop
を追加した
- Fix images not showing in notifications on OS X 10.9.
- OS X 10.9 の通知機能で画像が表示されない問題を修正
対応
各種変更の詳細と対応方法をまとめる。
非推奨 API の警告
非推奨の API の使用が警告されるようになった。例えば BrowserWindow.loadUrl
を呼び出すと以下のように警告される。
(electron) loadUrl is deprecated. Use loadURL instead.
対象となる API は廃止される可能性が高いので早期に修正すること。警告を抑止するなら Main プロセス冒頭で process.noDeprecation
に true
を代入すればよい。
process.noDeprecation = true;
この対応により警告が抑止されることを確認。しかし警告はアプリを修正するための重要なヒントであり、表示による動作への影響もないため抑止しないほうがよいだろう。
public API の electron
モジュール移行
electron
モジュールが追加され公開 API はそちらに移行された。もしくはされる。これまで私が使用してきたものだと ipc
や shell
が対象になっている。
個別の API リファレンスに掲載されているサンプルでは変更後のコードになっているため、ひととおり目を通しておいたほうがよい。electron
移行にともない参照方法も変更されている。require
を利用するなら electron
配下から読み込む。
const ipcMain = require( 'electron' ).ipcMain;
Modules 形式ならば electron
に対して明示的に名前指定すればよい。
import { ipcMain } from 'electron';
私は Modules 形式を利用するときの命名を PascalCase にしている。しかし ipcMain
などは camelCase となるため一貫性が崩れる。またユニット テストで IPC や Shell API をモック化したくなるかもしれない。そのためこれらは require 形式で読み込み、その参照を従属するインスタンスに伝搬する方式で設計している。
import DialogManager from './DialogManager.js';
import WindowManager from './WindowManager.js';
class Main {
constructor() {
// 共有される標準 API
this._ipc = require( 'electron' ).ipcMain;
this._shell = require( 'electron' ).shell;
// this を渡すことで従属するインスタンスは間接的に API を参照する
this._windowManager = new WindowManager( this );
this._dialogManager = new DialogManager( this );
}
}
徹底するなら App
や BrowserWindow
なども間接参照にするべきだが、とりあえずは electron
配下のものだけにしている。
ipc
モジュールから ipcMain
と ipcRenderer
への移行ipc
モジュールが非推奨になった。代りに Main プロセスは ipcMain
、Renderer プロセスでは ipcRenderer
を使用する。
const ipcMain = require( 'electron' ).ipcMain;
ipcMain.on( 'asynchronous-message', ( ev, arg ) => {
console.log( arg ); // prints "ping"
ev.sender.send( 'asynchronous-reply', 'pong' );
} );
ipcMain.on( 'synchronous-message', ( ev, arg ) => {
console.log( arg ); // prints "ping"
ev.returnValue = 'pong';
} );
ipcRenderer
はイベント ハンドラも変更されている。従来は
ipc.on( 'message', ( arg ) => {
} );
となっていたが新ハンドラは第一引数にイベント オブジェクトを取る。インターフェース設計が Main/Renderer プロセスで統一されて分かりやすくなった。
ipcRenderer.on( 'requsetMessage', ( ev, arg ) => {
ev.sender.send( 'responseMessage', 'I am a Renderer' );
従来は Renderer プロセスのハンドラから Main プロセスに返信したいなら通常の send
を利用していた。新ハンドラでは Main プロセスと同様にイベント オブジェクトの sender
経由で直に返信できる。
BrowserWindow のオプションと API 名の変更
BrowserWindow のオプション名から -
が取り除かれた。例えば max-width
は maxWidth
になっている。リファレンス を確認すると chain-case
だったものは camelCase
へ改められたようだ。chain-case
だと JavaScript のオブジェクト名をクォートする必要があり面倒。また chain-case
とそうではないものがオブジェクト内に混在しているときにクォートで統一すべきか悩んだものだが、こうした問題が解消された。
API 名の Url
という表記が URL
に変更されている。代表的なものだと BrowserWindows の loadUrl
が loadURL
になった。
BrowserWindow の新しいオプション名については -
で検索してリファレンスを確認しながら置き換えてゆく。API 名については loadUrl
の場合、非推奨とマークされているようで警告される。とはいえ、全 API がこうなっているか分からないので Url
で検索して個別対応するのが無難だろう。
特殊フォルダーの追加
app.getPath
で取得可能な特殊フォルダーが大量に追加された。これらはプラットフォーム標準のファイル置き場。ファイル操作の際 dialog.showOpenDialog
の defaultPath
へ指定するなどの用途が考えられる。
リファレンスにキー単位でフォルダの解説が掲載されているけれど、現時点では Windows のものだけ。よって実際に得られるパスを調べるため、Main プロセスで以下の関数を実行してみた。
function getPathSample() {
console.log( 'documents:', App.getPath( 'documents' ) );
console.log( 'downloads:', App.getPath( 'downloads' ) );
console.log( 'music:', App.getPath( 'music' ) );
console.log( 'pictures:', App.getPath( 'pictures' ) );
console.log( 'videos:', App.getPath( 'videos' ) );
}
OS X El Capitan 10.11.1 上の実行結果は以下。XXXX 部分はログインしているユーザー名。
documents: /Users/XXXX/Documents
downloads: /Users/XXXX/Downloads
music: /Users/XXXX/Music
pictures: /Users/XXXX/Pictures
videos: /Users/XXXX/Movies
Windows 8.1 での実行結果は以下となった。
documents: C:\Users\XXXX\Documents
downloads: C:\Users\XXXX\Downloads
music: C:\Users\XXXX\Music
pictures: C:\Users\XXXX\Pictures
videos: C:\Users\XXXX\Videos
OS X と Windows ならば追加されたフォルダーすべてのパスを得られた。Linux は試していない。Linux はディストリビューション間で特殊フォルダーの定義が統一されているも不明なのでパスを得られないかもしれない。
その他
その他の変更はバグ修正や普段あまり使わない機能に関するものなので割愛。
サンプル プロジェクト
今回の対応を実施したサンプル プロジェクトを公開。