Electronでアプリビルドまでのフロー


久しぶりにWindows向けの簡単なデスクトップアプリ開発する必要が発生したのですが、日常Mac環境の中、今更Windows環境でVisual Studio入れてFormアプリを書くのもなんなのでElectronで書こうと思った際のメモ。

## 追記

2019年10月30日に、Electron 7.0環境で動くよう一部コード書き換えました。

## やりたいこと

まあ、HTMLとかCSSとかJSは理解してるつもりなので、HelloWorldアプリをMac用, Win用の単体アプリとしてビルドするまでの流れを確認。


完成版は下記のような感じ。

![スクリーンショット 2019-01-25 8.32.30.png](https://qiita-image-store.s3.amazonaws.com/0/55188/0d870e56-d83f-f558-79fc-b1cabc32c6ec.png "スクリーンショット 2019-01-25 8.32.30.png")

## 前提

MacでWindows向けのデスクトップアプリを開発したい。


## 準備

### 作業スペースの確保

electronはpackage.jsonが無いと怒られる系のやつ。なので、npm initしてpackage.jsonを作っておく。


```bash
mkdir myApp
cd myApp
npm init -y
```

何も変えなくてもいいのですが、electronではエンドポイントをmain.jsとする文化のようなので変更します。

>script等は環境に合わせてお好みで（何も変更しなくても良い）。

```diff:package.json
{
+  "name": "myApp",
  "version": "1.0.0",
  "description": "",
+  "main": "main.js",
  "scripts": {
+    "start": "electron ."
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

### electronのインストール

globalでもいいのですが、ものすごい頻度でバージョンアップされるのでとりあえずローカルにインストール。
作業フォルダにて以下を実行。

```bash
npm i -D electron
```

>-Dは--save-devと同意。

### 必要なファイルの生成

main.jsがエンドポイントとなり、そこからindex.htmlを呼び出すような感じにするので、2つのファイルを先に作っておきます。

```bash
touch main.js index.html
```

## 実装

### main.js

実装内容は[ElectronのQuickStart](https://electronjs.org/docs/tutorial/first-app)にあるやつをベースに少し修正（ほぼまんまですが）。
Macだと少し余計な記述が必要らしい。

```js:main.js
const { app, BrowserWindow } = require('electron')

let win

function createWindow() {

    //ウインドウの作成
    win = new BrowserWindow({
        width: 400,
        height: 400,
        webPreferences: {
            nodeIntegration: true, //Electron6から必要らしい
        }
    })

    //ウインドウに表示する内容
    win.loadFile('index.html')

    //デバッグ画面表示
    // win.webContents.openDevTools()

    //このウインドウが閉じられたときの処理
    win.on('closed', () => {
        win = null
    })
}

//アプリが初期化されたとき（起動されたとき）
app.on('ready', () => {
    createWindow();
})

//全ウインドウが閉じられたとき
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

//アクティブになったとき（MacだとDockがクリックされたとき）
app.on('activate', () => {
    if (win === null) {
        createWindow()
    }
})
```

### index.html

実際のアプリとなるファイル。

```html:index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
</head>

<body>
    <h1>Hello World!</h1>
    We are using node
    <script>document.write(process.versions.node)</script>,
    Chrome
    <script>document.write(process.versions.chrome)</script>,
    and Electron
    <script>document.write(process.versions.electron)</script>.
</body>

</html>
```

## 実行（動作確認）

```bash
npm start
```

>npx electron . とかでもいい。

## パッケージング（electron-builderによるビルド）

単体で動くアプリケーション化する方法がいくつかあるが、electron-builderがいちばんメジャー？っぽいので使ってみます。electron-builderを使うとインストーラー形式で出力したり、アイコン設定等ができる。

まずはインストール。

```bash
npm install -D electron-builder
```

下記は最低限度。

package.jsonに記述することもできるが、独立したビルド条件をjsファイルにすることもできるみたい。
Windows用に下記のように書いてみた。

>zipした状態で、x64とia32(x86)用に出力する。targetをnsisとかにするとinstaller形式となる。

標準ではdistフォルダが作成され、そこの出力されるよう。gitつかうなら.gitignoreにdist/としたほうがよいかも。

```js:build-win
const builder = require('electron-builder');

builder.build({
    config: {
        'appId': 'local.test.app1',
        'win':{
            'target': {
                'target': 'zip',
                'arch': [
                    'x64',
                    'ia32',
                ]
            }
        }
    }
});
```

>appIdは必要に応じて変更。

Mac用。targetをdmgとかにもできる。

```js:build-mac
const builder = require('electron-builder');

builder.build({
    config: {
        'appId': 'appId': 'local.test.app1',,
        'mac':{
            'target': 'zip',
        }
    }
});
```

ビルドの実行。

```bash
node build-win
node build-mac
```

環境に関係なくWin(ia64)やMac用のexeファイルはビルドされるっぽい。
なお、Win32環境はWindowsじゃないとビルドできなくなったみたいです。