0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【2022年】Electronについてリサーチした

Last updated at Posted at 2022-05-22

メモ

WEB技術でデスクトップアプリケーションを開発できるFWのElectronについて、メモしました。

目次

  • IPC通信について:メインプロセスとレンダラプロセス
    • IPC通信とは何か?
  • main.jsの説明
    • ipcMain.handle()メソッド
  • renderer.jsの説明
    • ipcRenderer.invoke()メソッド
  • preload.jsの説明
  • アプリケーションの実行方法

IPC通信とは何か?

メインプロセス側: main.js

ipcMain.handle()メソッドを使用します。

ipcMainモジュールはメインプロセスで、レンダラプロセスから送信されるメッセージを受信して処理します。
基本的にメインプロセスは受け身で受信したら送信元のレンダラプロセスに対して返信するみたいな動きになります。

レンダラプロセス側: renderer.js

ipcRender.invoke()メソッドを使用します。
メインプロセスに対して、同期、非同期のメッセージを送信できるメソッドが用意されています。もちろん返信を受け取ることもできます。

メインプロセスとレンダラプロセスの橋渡し役: preload.js

preload.jsでは Node.jsの機能が使用できます。

preload.jsにてipcRendererを利用できるようにするためには、メインプロセスであるmain.js内で下記のように設定しておく必要があります。

main.js
mainWindow = new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    // ここに、preload.jsに関する記述を行う
    preload: path.join(__dirname, 'preload.js')
  }
})

エントリポイントについて

Electronと似ているFWのNW.jsなどもWEB技術でデスクトップアプリの開発が可能ですが、Eletronの差異の1つにエントリポイントの指定方法があります。

Nw.jsの場合は、HTMLファイルを直接指定するようなのですが、Electronの場合は、main.jsといったJSファイルをpackage.jsonなどでエントリーポイントとして指定し、そのJSファイルのメソッド中で、mainWindow.loadFile("index.html");といった形で、具体的なHTMLエントリーポイントを柔軟に制御することができるようです。

メインプロセスについて

最初に起動するエントリポイントとなっているファイル、package.jsonの “main” に設定されているjsファイルが動くのがメインプロセスです。
Node.jsで動くのでOSネイティブのAPIを使えます。
Fileの読み書きなどを行う場合はこのメインプロセスで行う必要があります。
このメインプロセスを終了するとアプリケーションが終了します。

レンダラプロセスについて

画面のレンダリングを行っているプロセスです。ブラウザで表示されているhtmlファイルの数だけ、つまりタブの数だけレンダラプロセスがあるイメージです。
ElectronはChromiumで動いているのでこのような仕組みになっています。
したがって当然ブラウザ上で動くJavaScriptと同じ機能しか使えません。

ElectronではIPCを行うためのモジュールである ipcMainipcRendererが提供されます。これを使ってプロセス間での通信を実現します。

IPCには同期通信と非同期通信の2種類があります。基本的には非同期で使うのがいいと思います。

contextBridgeについて

ただし、contextBridge API の用法には注意が必要な点もあります。たとえば以下のコードは、contextBridge を利用しているにもかかわらず危険です。

この記述は危険

この myAPI.renderer() は ipcRenderer という強力な API を無制限かつ包括的にレンダラープロセスへ曝してしまっているからです。

const { ipcRenderer, contextBridge } = require('electron')

contextBridge.exposeInMainWorld('myAPI', {
  // NGな記法
   renderer: ipcRenderer
})

推奨する記法

IPC ベースの API を公開する正しい方法は、代わりに IPC メッセージごとに 1 つのメソッドを提供することです。

「IPCメッセージ(のチャンネル)ごとに1つのメソッドを提供する」ように書き直すと次のようになります。

const { ipcRenderer, contextBridge } = require('electron')

contextBridge.exposeInMainWorld('myAPI', {
  openDialog: async () => ipcRenderer.invoke('open-dialog'),
})

アプリケーションの起動・実行

npx electron ./srcで可能です。

余談ですが、package.jsonのscriptsに下記を記述することで、コマンドをカスタマイズできます。

"start": "npx electron ./src"

これで、npm run startで起動することができます。

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?