[Electron] 5分でWin&Macのクロスプラットフォームアプリを作ろう


# 背景
[Electron](https://electron.atom.io/)というエンジンを使えば、JavaScript + HTML + CSS で
簡単にクロスプラットフォームアプリが作れ、
WindowsならばEXE形式で配布することも容易です。

また、[Monaca](https://ja.monaca.io/) (HTMLハイブリッドアプリエンジン)
と全く同じコードを使いまわすことができ、最終的に、
Win&Mac&Android&IPhoneの全て同一のコードで動かすことが出来ます。

参照：[Android＆iOS＆Win＆Macが同じコードで動く！超マルチアプリを作ろう[Monaca × Electron]]
(http://qiita.com/youwht/items/cac4c6a0f725d7689f96)

# 本投稿の内容

 本投稿では、 誰でも５分程度でElectronのアプリが作れるように
 ①環境構築 ＋ ②サンプルコードの開発 ＋ ③実行 ＋ ④配布用パッケージング
のチュートリアルを行います。

> 他の多くのサイト/記事では、Electronのバージョンにより書き方が異なる点について、
> 解説していなかったり、配布方法（パッケージング）までは記載していなかったりするため、
> 似たような記事がありながらも、改めて投稿することにしました。
> 本投稿の手順のみで、環境構築～アプリ作成～パッケージングまで一気通貫で実行出来ます。


# ① Electronのインストール/環境構築
### 1. 前提

  前提環境を記載しますが、どの環境でも同様です。
  
  *  環境　　：Windows10
  * コマンド：PowerShell

### 2. Node.jsのインストール

  下記ページよりインストールします。 
  [https://nodejs.org/en/](https://nodejs.org/en/)
  執筆時のバージョン：　v6.11.1 LTS

### 3. Electronのインストール

  * 以下のコマンドでインストールします。  
    
```shell-session
npm install electron -g
```
 
  * インストール後、以下のコマンドでバージョンが確認出来ます。(執筆時：v1.6.11)
  
```shell-session
electron -v 
```
  
  * インストール後、以下のコマンドでGUIを起動出来ます。
  
```shell-session
electron
```

### 4.  配布/EXE化用パッケージャーのインストール

  * 以下のコマンドで、asarというツールと、パッケージング用ツールをインストールします。
  
```shell-session
npm install -g asar
npm i electron-packager -g
```

### 5. (任意) 旧バージョンのElectronを入手する

  * v0.36.4のファイルは以下からダウンロードできます。
    [Electron/v0.36.4](https://github.com/electron/electron/releases/tag/v0.36.4)
    electron-v0.36.4-win32-x64.zip を入手してください。

  * EXEを叩けば、コマンドラインのelectronと同様にGUIが立ち上がります。

  * Electronは、0系と1系では、一部APIの仕様が変更されているため、
    メジャーバージョンが異なる場合は多少の手直しが必要になります。


# ② Hello Electron (サンプルコード) の作成
### 1. 任意のフォルダを作成し、以下３ファイルを作ります。 

  * index.html

  * package.json

  * app.js 

> 以降では仮に「SampleAppFolder」に上記ファイルを作成したとします。
>  ※コード上にこの名前は出てきません。実行やパッケージのコマンドでの指定時のみ出てきます。


### 2. index.html
  
  普通のHTMLと同様のファイルです。CSSやJavaScriptの組み込みもOKです。


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

<head>
<meta Http-Equiv="content-type" Content="text/html;charset=UTF-8">
<title>Electronテストアプリ</title>
</head>

<body>
Hello Electron
</body>
</html>
```    


### 3. package.json

  「app.js」はここで指定しています。


```json:package.json
{
  "name": "test-app",
  "version": "0.9.0",
  "description": "test-app",
  "main": "app.js",
  "author": "Name",
  "scripts": {
    "start": "electron ."
  }
}
```


### 4. app.js

  ☆重要☆ Eclectronの0.3系と、1.X系で書き方が異なります。
  ここでは両方の例を載せておきます。

  * 0.3系


```js:app.js
'use strict';
var app = require('app');
var BrowserWindow = require('browser-window');
var mainWindow = null;

//クラッシュレポート
require('crash-reporter').start();

//全ウィンドウを閉じたとき（Xボタン）の処理
app.on('window-all-closed', function() {
  if (process.platform != 'darwin')
    app.quit();
});

//アプリケーションの初期化終了後に呼び出される処理
app.on('ready', function() {
    //メインウィンドウの定義：サイズ以外にもいろいろ設定可能
    mainWindow = new BrowserWindow(
    {
        width: 600, 
        height: 400,
        'min-width': 300,
        'min-height': 200,
    }
    );
    //現在実行中のファイルディレクトリパスの下のindex.htmlを読みに行く。
    mainWindow.loadUrl('file://' + __dirname + '/index.html');
    //メインウィンドウ終了時の処理
    mainWindow.on('closed', function() {
        mainWindow = null;
    });
});
```


  * 1.X系



```js:app.js
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

let mainWindow = null;
app.on('ready', () => {
    //メインウィンドウの定義：サイズ以外にもいろいろ設定可能
    mainWindow = new BrowserWindow(
    {
        width: 600, 
        height: 400,
        'min-width': 300,
        'min-height': 200,
    }
    );
    //現在実行中のファイルディレクトリパスの下のindex.htmlを読みに行く。
    mainWindow.loadURL('file://' + __dirname + '/index.html');
    //メインウィンドウ終了時の処理
    mainWindow.on('closed', function() {
        mainWindow = null;
    });
});
```


  * 備考： 0.3⇒1.Xのバージョン違いについて、記載が変わる点をいくつか例を示します。
      * var remote = require('remote');  ⇒ const remote = require('electron').remote;
      * mainWindow.loadUrl ⇒ mainWindow.loadURL
      * var clipboard = require('clipboard');  ⇒ const {clipboard} = require('electron');
      * 主にnode.js系の処理の書き方等が違っています。
        他のHTML5製ツールへの移植性を確保するためにも、
        純粋なJavaScriptコードと、ファイル/クリップボード操作等の処理をするコードは、
       ファイルを分けて作成しておくことを強く推奨します。
       

# ③ Hello Electron (サンプルコード) の実行
### Case1:  GUIにドラッグ＆ドロップして実行する方法
  
環境構築時に記載の方法で、GUIを立ち上げてください。
  
   * コマンドラインにて「electron」を実行する。
   * ダウンロードしてきた「electron.exe」を叩く。

立ち上がったGUI上の「Drag your app here to run it」と記載されている所に、
作成したアプリのフォルダをドラッグ＆ドロップします。

index.htmlの内容の通り、「Hello Electron」と
表示されてば成功です！

### Case2:  コマンドラインで実行する方法

コマンドラインからでも、以下のように実行可能です。

```shell-session
electron .\SampleAppFolder\
```

# ④ 配布用にEXEにパッケージング
以下のコマンドで、パッケージング＆暗号化することが出来ます。
バージョン指定は必須なので、electron -v で事前に確認してください。
JavaScriptで作成した場合、コードが見られやすいという弱点がありましたが、
このようにパッケージング時に暗号化して隠蔽出来ることもelectronの強みです。


```shell-session
# 32bit,64bit両方のexeを出力する場合のサンプルコマンド
electron-packager ./SampleAppFolder PackagedFolder --platform=win32 --arch=all --version=1.6.11 --overwrite --asar

# 32bitのexeのみ。 macの場合も同様にarchオプションを変更してください。
# electronのバージョン指定（0.3系の場合このようにしてください）
# 256*256のiconを追加
electron-packager ./SampleAppFolder PackagedFolder --platform=win32 --arch=ia32 --version=0.36.4  --icon=./YourIcon.ico  --overwrite --asar
```


# おつかれさまでした。
electronを使うことで、環境構築から配布用のファイルの作成まで、
簡単に出来たのではないでしょうか？


TODO/更新用メモ：

* index.htmlを改変することで、様々なアプリが作れます。
* CSSを工夫することで、ボタンやデザインの実装等が綺麗に行えます。Web技術を使いまわせます。
⇒ より高度なカスタマイズ方法について別途投稿予定。

* Node.jsを使えるため、通常のJavaScriptのみと異なり、ファイル操作等も実装可能です。
 ⇒　ファイル操作や、Macでのコピペのノウハウについてそのうち投稿。

* Monaca × onsenUI のコードをそのまま移植できます。
   スマートフォンアプリとデスクトップアプリを同一のコードで作ることが出来ます。
 ⇒ 参照：[Android＆iOS＆Win＆Macが同じコードで動く！超マルチアプリを作ろう[Monaca × Electron]]
(http://qiita.com/youwht/items/cac4c6a0f725d7689f96)


* JavaScriptによって外部サービス（API）を利用することも出来ます。
  ⇒ 別途投稿予定。

* 他にもHTML5/Electron/Monacaの統合ノウハウとして投稿を検討しています。

以上。 

----
この系統の投稿を拡充させてほしいかたは「いいね」をお願いします。
（反応の多いニーズのある話から記載するため）