Electronの手習い〜Electron環境からパッケージ化まで〜

Electronってどういうことができるのか全く知らない状態からスタートです。

Electronとは？についての参考資料
- [Electron 本家サイト](http://electron.atom.io/) 
- [HTML5でクロスプラットフォームなデスクトップアプリを開発できる「Electron」とは](https://codezine.jp/article/detail/8782) 
- [Electron 1.0でデスクトップアプリ開発超入門――動作の仕組み、基本的な使い方、セキュリティの懸念点](http://www.atmarkit.co.jp/ait/articles/1605/18/news017.html)
- [本家サイトを翻訳してくれているページ発見](https://github.com/electron/electron/tree/master/docs-translations/jp)　助かる。。

★　本家サイトからのデモファイルDL時に混乱したこと
http://electron.atom.io/#get-started 
に「Downlode for mac」があったのでそれをDLして中身を確認しようとしました。
しかし、これは**「Electronで開発したアプリでは、どのようなことが行えるか」**がわかるappであり、期待しているソースファイルはありませんでした。
自分でつくった場合のパッケージの形がこういうapp拡張子のものになる感じですね。

ソースサンプルは [Docs画面のQuick Start](http://electron.atom.io/docs/tutorial/quick-start/)のチュートリアルから進めればいい感じです。
＜参照＞
[30分で出来る、JavaScript (Electron) でデスクトップアプリを作って配布するまで](http://qiita.com/nyanchu/items/15d514d9b9f87e5c0a29)

# Electronの特徴
・　HTML、CSS、JavaScriptといったWebフロントエンド技術を使って開発できる　
・　Node.jsとChroniumで動作する
・　WindowsやMac（OS X）、Linuxなどのデスクトップ向けアプリを開発できる

# Electronアプリ環境をつくる
必要なインストール
- node環境（npmモジュールをインストールするため）
- Electronアプリデバッグ用モジュール
- Electronアプリパッケージング用モジュール

---
本家サイトをみると以下のバージョンが書かれていました（20160628現在）
Electron:1.2.5　Node:6.1.0　Chromium:51.0.2704.103　V8:5.1.281.65

これはElectron:1.2.5にはNodeとかはこのバージョンで内包されているよ的な感じらしい。
20160628現在のNode最新はv6.2.2のようなのだが、ローカルも合わせておいたほうが変なことにはまらないと思うのでv6.1.0にする。

Nodeはすでにインストール済みとします。
Nodeの設定は[macでNode.jsの環境設定](http://qiita.com/tagosaku324/items/bf1fe149c38c99728c72)参照
バージョン違いでインストールされていたら適切なバージョンをインストールします。

### Node v6.1.0 インストール
```text:node最新情報確認〜v6.1.0インストールまで
$ nvm ls-remote
        v0.1.14
        v0.1.15
:
         v6.2.1
         v6.2.2
$ node -v
v0.12.8
$ nvm install v6.1.0
Downloading https://nodejs.org/dist/v6.1.0/node-v6.1.0-darwin-x64.tar.gz...
######################################################################## 100.0%
Now using node v6.1.0 (npm v3.8.6)
Creating default alias: default -> v6.1.0
$
```
### デバッグ用モジュールインストール
Electronアプリをデバッグ目的でビルドし実行するには、npmモジュール「electron-prebuilt」を使います。

```text:electron-prebuiltのインストール
$ npm -g install electron-prebuilt
/Users/***/.nvm/versions/node/v6.1.0/bin/electron -> /Users/***/.nvm/versions/node/v6.1.0/lib/node_modules/electron-prebuilt/cli.js

> electron-prebuilt@1.2.5 postinstall /Users/***/.nvm/versions/node/v6.1.0/lib/node_modules/electron-prebuilt
> node install.js

Downloading electron-v1.2.5-darwin-x64.zip
[============================================>] 100.0% of 42.61 MB (358.03 kB/s)
/Users/***/.nvm/versions/node/v6.1.0/lib
└─┬ electron-prebuilt@1.2.5 
  ├─┬ electron-download@2.1.2 
 :
$
```
### パッケージング用モジュールインストール
パッケージングするには、npmモジュール「electron-packager」を使います。
（Macの「.app」形式のファイル、Windowsの「.exe」形式のファイルなどにする）

``` text:electron-packagerのインストール
$ npm -g install electron-packager
/Users/***/.nvm/versions/node/v6.1.0/bin/electron-packager -> /Users/***/.nvm/versions/node/v6.1.0/lib/node_modules/electron-packager/cli.js
/Users/***/.nvm/versions/node/v6.1.0/lib
└─┬ electron-packager@7.1.0 
  ├─┬ asar@0.11.0 
 :
$
```

# Electronでアプリケーションを作成

★補足20160704 手っ取り早く確認したいならば・・・
TOP画面の下の方にある[Quick Start](http://electron.atom.io/)のところにある
![スクリーンショット 2016-07-04 15.57.40.png](https://qiita-image-store.s3.amazonaws.com/0/39911/d221a0dd-aeb5-9bc6-41d8-f18bae06a927.png)
ここを実行すればelectron起動までの確認はできますし、ソースの書き方の確認もできます。

```shell-session:デバッグ実行まで出来ちゃいます
$ git clone https://github.com/electron/electron-quick-start
$ cd electron-quick-start
$ npm install && npm start
```

### プロジェクトの作成
[Quick Start　画面中　Write your First Electron App](http://electron.atom.io/docs/tutorial/quick-start/) にあるようにファイルを用意します。

```
.
├── index.html
├── main.js
└── package.json
```
*npm init*　を使わなくてもいきなり *package.json* を作ることもできますが、今回は　*npm init*　を使って　*package.json* を作りました。
*package.json* の中は後からでも書き換えれるので流されるままに対話します。

```text:ディレクトリ作成、package.json作成
$ mkdir sample
$ cd sample
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (sample) tago-app
version: (1.0.0) 0.1.0
description: サンプル
entry point: (index.js) main.js
test command: 
git repository: 
keywords: 
author: tagosaku
license: (ISC) MIT
About to write to /Users/***/NodeSampleTmp/electron/sample/package.json:

{
  "name": "tago-app",
  "version": "0.1.0",
  "description": "サンプル",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "tagosaku",
  "license": "MIT"
}

Is this ok? (yes) yes
$
```
main.js コピーしてみた。

```js:main.js
// electronモジュールを読み込み
const electron = require('electron');
const {app} = electron;
const {BrowserWindow} = electron; //ウィンドウを表す[BrowserWindow]はelectronモジュールに含まれている

// 新しいウィンドウ(Webページ)を生成
let win;
function createWindow() {
  // BrowserWindowインスタンスを生成
  win = new BrowserWindow({width: 800, height: 600});
  // index.htmlを表示
  win.loadURL(`file://${__dirname}/index.html`);
  // デバッグするためのDevToolsを表示
  win.webContents.openDevTools();
  // ウィンドウを閉じたら参照を破棄
  win.on('closed', () => {   // ()は　function ()と書いていい
    win = null;
  });
}
// アプリの準備が整ったらウィンドウを表示
app.on('ready', createWindow);
// 全てのウィンドウを閉じたらアプリを終了
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});
```
Electronアプリでは「electron」モジュールが全ての基礎になる。
Electronアプリのさまざまな制御を行うために使うのが「app」オブジェクト

★　補足：20160707
>
Electronでよく見るサンプルの*main.js*の出だしは
>
```js:main.js
　：
var app = require('app');
var BrowserWindow = require('browser-window');
　：
```
こんな感じになってるけどそのままではエラーになって動かないです。
今のElectron:1.2.5バージョンは*electron*の下に*app*などが移っているから*electron*を呼び出さないとエラーになります。
>
```
$ electron .
App threw an error during load
Error: Cannot find module 'app'
    at Module._resolveFilename (module.js:438:15)
    at Function.Module._resolveFilename (/Users/***/.nvm/versions/node/v6.1.0/lib/node_modules/electron-prebuilt/dist/Electron.app/Contents/Resources/electron.asar/common/reset-search-paths.js:47:12)
    at Function.Module._load (module.js:386:25)
    at Module.require (module.js:466:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/***/NodeSampleTmp/electron/yawcam_cal/main.js:3:11)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:456:32)
    at tryModuleLoad (module.js:415:12)
```

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>
```

### デバッグ実行
Electronアプリのディレクトリで、次のコマンドを実行するとデバッグ実行されます。

```
$ electron .

```
画面がたちあがってきました！
![スクリーンショット 2016-06-28 17.11.02.png](https://qiita-image-store.s3.amazonaws.com/0/39911/bf215196-dcb5-cac9-92f9-b8fae39336a1.png)
ウィンドウを閉じると画面は終了しますが、Macの場合はelectronアプリは終了していません。
ターミナルでControl+Cを入力すると終了します。

### パッケージング
MacとWindows向けにパッケージングします。

```
$ electron -v
v1.2.5
$ electron-packager . sample --platform=darwin,win32 --arch=x64 --version=1.2.5
Packaging app for platform darwin x64 using electron v1.2.5
Downloading electron-v1.2.5-win32-x64.zip
[============================================>] 100.0% of 52.47 MB (90.38 kB/s)
Packaging app for platform win32 x64 using electron v1.2.5
Wrote new apps to:
/Users/***/NodeSampleTmp/electron/sample/sample-darwin-x64
/Users/***/NodeSampleTmp/electron/sample/sample-win32-x64
$ ls
index.html		package.json		sample-win32-x64
main.js			sample-darwin-x64
```
（sampleというアプリ名にしています。）
実行終了すると、

+ windows 64bit用パッケージフォルダ：sample-win32-x64 
+ mac 64bit用パッケージフォルダ：sample-darwin-x64　 

ができます。
パッケージフォルダ内の　winならsample.exe、macならsample.appを叩くとデバッグブラウザで確認したような画面が表示されます。
*win.webContents.openDevTools();* が書かれたままだと開発ツールも起動されてしまうので、消してください。

```text:コマンド実行の引数
electron-packager ｛ソースディレクトリ｝ ｛アプリ名｝ --platform=｛プラットフォーム｝ --arch=｛アーキテクチャ｝ --version （バージョン｝ ［その他のオプション ...］

platform ･･･ all, linux, win32, darwin のいずれかを選択。
            「--all」は全部入りのパッケージング。
            「darwin」はmacのこと。複数選択はカンマ区切り。
arch ･･･ all, ia32, x64 のいずれかを選択。
version ･･･ Electronのバージョンを指定。(*electron -v*で確認)
```
![スクリーンショット 2016-06-28 18.54.21.png](https://qiita-image-store.s3.amazonaws.com/0/39911/4bfa4032-114b-5fe4-923c-9229c115a721.png)

★ 補足：20160630
Windwos 32bit用なんだけどなという場合は*--platform=win32 --arch=ia32* だけでできます。

```
$ electron-packager . sample --platform=win32 --arch=ia32 --version=1.2.5
Packaging app for platform win32 ia32 using electron v1.2.5
Wrote new app to /Users/***/NodeSampleTmp/electron/sample/sample-win32-ia32
$ 
```
ただし、一度electronを実行したフォルダには *[＊＊＊-win32-ia32]*とかフォルダができてます。
そのフォルダ構成の状態でmac用をつくろうかな。って*　electron-packager* を再度実行しちゃうと・・・
予定のパッケージング用ファイルだけでなく、*[＊＊＊-win32-ia32]*まで含まれてパッケージ化されるので気をつけてください。

```text:余計なファイルまでパッケージしてしまうだ・・・
.
├── index.html
├── main.js
├── package.json
├── sample-win32-ia32
│   ├── LICENSE
 :
```
Windows用でElectronの環境を整えたいのなら、
[初めてのElectron](http://qiita.com/YoungjaeKwon/items/9a51dcc45533b2c52955)
こちらが参考になるかもしれません。

macで*electron-packager*実行後にできたwindows用のフォルダ一式をwindowsマシンに持って行き、exeを叩けば作成したものが表示されます。

アプリのウィンドウを変えたい場合は、*browser-window API* で変更できるのでいろいろいじってみよう。。
[Electron　本家Docs参照](http://electron.atom.io/docs/api/browser-window/)

### アイコン変えたいよね 20161115 追加
electron-packagerの`icon`オプションで簡単に変えれます。

```
$ electron-packager . sample --platform=win32 --arch=ia32 --icon=icon.ico --version=1.2.6  # Windows

$ electron-packager . sample --platform=darwin --arch=x64 --icon=icon.icns --version=1.2.6  # Mac
```
★ macの場合、いろんなサイズの画像を用意してicnsにしますよね？
１つのpngからサクッと変換してくれたら楽ちんなのにというので探して見つけたアプリが
「Image2icon」AppStoreからすぐに見つかります。
freeでできる範囲で十分つくれました。
![スクリーンショット 2016-11-15 15.09.00.png](https://qiita-image-store.s3.amazonaws.com/0/39911/28a0ae1e-1501-e144-5f9d-89a109864277.png)　pngファイルをドロップする
![スクリーンショット 2016-11-15 15.09.15.png](https://qiita-image-store.s3.amazonaws.com/0/39911/2908749b-9037-6fbf-5bd2-bb188c83a6a0.png)![スクリーンショット 2016-11-15 15.09.27.png](https://qiita-image-store.s3.amazonaws.com/0/39911/326c0474-f66e-073a-c562-643e38742260.png)![スクリーンショット 2016-11-15 15.09.53.png](https://qiita-image-store.s3.amazonaws.com/0/39911/d897c683-103e-3c89-858d-ab783179c954.png)![スクリーンショット 2016-11-15 15.11.54.png](https://qiita-image-store.s3.amazonaws.com/0/39911/eb24aaed-5bea-f770-da5e-17503f51a9c7.png)
icns選択して保存したら、できあがり。


## おまけ
*index.html* のファイル名を記載しているのは *main.js*
なので、昔作った別ファイルに置き換えてみた。

[カレンダー試行錯誤編:datepicker複数月表示](http://qiita.com/tagosaku324/items/acd9f2113fe770d341e5)

```js:main.js
 :
  win.loadURL(`file://${__dirname}/index_range.html`);
 :
```
しかし、jqueryが読み込めなていないというjavascriptエラーが起きた。

```html:動かない
 :
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.min.js"></script>
 :
```
解決策は

```html:Electronで動かすためにはこんな感じにする
 :
<script>
window.nodeRequire = require;
delete window.require;
delete window.exports;
delete window.module;
</script>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.min.js"></script>
 :
```
無事に動いた!
![スクリーンショット 2016-06-28 19.41.54.png](https://qiita-image-store.s3.amazonaws.com/0/39911/203c17a1-b8e9-725e-a12b-4f03e911ec61.png)

補足：20160704 JSファイル読み込みの別の方法

```html:requireで読み込む方法
 :
</script>
require('jquery.js')
require('jquery-ui.min.js')
</script>
 :
```

★　補足：20160707
[ELECTRONでJQUERYを使ってみる．](http://daifuku-p.org/w/?p=810)
ここのサイトのように*JQUERY_AFTER.JS*を作るのが一番スマートな書き方なような気がしました。