Electronでデスクトップアプリをサクッと作る(ボタンイベント付き）

Electonは、JavaSriptとHTML、CSSを知っていればアプリを作ることができるフレームワーク。

公式のドキュメントが日本語対応しているところもうれしい。
https://www.electronjs.org/

ビルド時のコマンドにオプションを指定すると、winodwsやMac、Linux用のアプリも作れる。

## 1. インストール
`electron`は、devDependenciesにインストール。
```console
npm init -y
npm i -D electron
```

## 2. index.htmlを用意
ルートディレクトに`index.html`を作成。
アプリを実行したときのトップページになる。
```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'self'"
    />
    <meta
      http-equiv="X-Content-Security-Policy"
      content="default-src 'self'; script-src 'self'"
    />
    <title>Hello from Electron renderer!</title>
  </head>
  <body>
    <h1>Hello from Electron renderer!</h1>
    <p>👋</p>
    <p id="info"></p>
  </body>
  <script src="./renderer.js"></script>
</html>
```

## 3. main.jsを用意
Electronのモジュールを扱うためのjsファイル。
Common.js形式に対応している。
```js:main.js
const { app, BrowserWindow } = require('electron');

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
  });

  win.loadFile('index.html');
};

app.whenReady().then(() => {
  createWindow();

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
```

package.jsonには、srciptを記入しておく。
```json:package.json
{
  "name": "electron_quick",
  "description": "Hello World",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "devDependencies": {
    "electron": "^20.1.0"
  }
}
```
ここまで用意できたら`npm start`で実行。
アプリを起動できるようになる。
![Screen Shot 2022-08-28 at 5.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482880/b149b8c0-1180-d95b-7ba5-5f64b21b536a.png)

## 4. ボタンをつけてみる
適当なイベントを持ったボタンをつけた場合のサンプル。
`index.html`に読み込んだ`renderer.js`から`main.js`のプロセスを呼ぶ。

ボタンを用意。
```html:index.html
<button id="btnTest">button</button>
```

グローバル変数にメソッドを定義。
```js:preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('apis', {
    runClickEvent: async () => ipcRenderer.invoke('click-event'),
});

```

イベントをセット。
```js:renderer.js
const btnTest = document.getElementById('btnTest');
btnTest.addEventListener('click', async () => {
    await window.apis.runClickEvent();
});
```

`main.js`でプロセスをリッスンする。
```js:main.js
const { app, BrowserWindow, ipcMain, dialog } = require('electron')
const path = require('path')

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
    },
  });

  // IPC handler
  ipcMain.handle('click-event', async (_e, _arg) => {
    const options = {
        type: 'info',
        title: 'quick start',
        message: 'hello world!',
        detail: 'description'
    };
    dialog.showMessageBox(options);
  });

  ipcMain.on('close', () => {
    app.quit();
  });

  win.loadFile('index.html');

  //win.webContents.openDevTools();
};

app.whenReady().then(() => {
  createWindow();

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });
});

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

```

ボタンをクリックで、アラートを鳴らすイベントが簡単にできた。
![Screen Shot 2022-08-28 at 7.46.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482880/5ba5641d-a58c-9e9c-9039-944189efd2c7.png)

今回作ったサンプルコードはこちら
https://github.com/pixcelo/electron_quick