KMC例会講座「Electronを始めるための準備体操」

# これは何

- この資料は[京大マイコンクラブ](https://kmc.jp/)の例会講座で@[pastak](https://twitter.com/pastak)が行った発表の資料です
- あまりWeb技術に馴染みがないであろうKMC部員の皆さんにElectronに興味を持って頂くというのをゴールにしてざっくりとElectronの概要について紹介します

# 自己紹介

- pastak
- parttimer at Nota

## pastakとElectron

ちょくちょく小物を書いている

- [pastak/gyazo-menubar](https://github.com/pastak/gyazo-menubar)
    - [ツールバーから直近のGyazoった画像にシュッとアクセス出来るアプリをElectronで書いた - Pastalablog in はてな](http://pastak.hatenablog.com/entry/2015/06/02/021704)
    - ![](https://camo.githubusercontent.com/56fd76fad91a6d101d0a80669044b769661bc83e/68747470733a2f2f692e6779617a6f2e636f6d2f62343239656330333536333964373732636262386561383566356430346437362e676966)
- [pastak/gyazotlight](https://github.com/pastak/gyazotlight)
    - [GyazoをSpotlight風のUIで検索できるElectronアプリを公開しました。ブラウザ拡張もあるよ。 - Pastalablog in はてな](http://pastak.hatenablog.com/entry/2015/10/14/210524)
    - ![](https://i.gyazo.com/7637a268a226c80ac96f7c936cd6bfa6.gif)

# Electronって何？

- github.com/atom/electron
- 旧名 Atom-shell
- AtomEditorでの知見を切り出して汎用化
    - NodeJS + Chromium + OS API
    - Webベースの知識を用いてデスクトップアプリケーションが作れる
    - Windows / MacOSX / Linux

# Electronでアプリケーションを書くことについての検討

## WebApp

- 個人だとheroku/AWS/GCEなどの上に構築
- アクセス/利用開始が比較的容易
- JSとかをそれなりに書くとブラウザ毎に色々なことがある
    - ~~IEとかIEとかIEとか~~

## Chrome Apps

- Chrome Web Storeで配布
- Chrome/Chromium上で動かす
    - Chromeを入れていればどの環境でも利用可能
- Chromeの外に影響することも出来るがあまり容易ではない

## Electron

- 配布機構は自前で用意
    - MacAppStoreに上げられるようになりそう
        - https://github.com/atom/electron/pull/2920
- タスクバーなどOSのUI機構を比較的容易に利用できる

# HTML/CSS知ってますか？

- ElectronでのUIは一部を除いて大体HTMLで記述することになる。
- CSS良い感じに書くのはムズい(個人の意見です)
    - http://photonkit.com/
[![https://gyazo.com/2b6afed884268646c821577f7825d6b6](https://i.gyazo.com/2b6afed884268646c821577f7825d6b6.png)](https://gyazo.com/2b6afed884268646c821577f7825d6b6)
    - https://github.com/gabrielbull/react-desktop
![](https://raw.githubusercontent.com/gabrielbull/react-desktop/master/docs/screenshots/osx.png)
- 各位頑張ろう

# JavaScriptって知ってますか？

- KMC内でJSについて学ぶ場合
    - [ECMAScript6勉強会](http://kmc.hatenablog.jp/archive/category/ECMAScript6%E5%8B%89%E5%BC%B7%E4%BC%9A)
    - [JavaScriptで世界平和2014](http://kmc.hatenablog.jp/archive/category/JavaScript%E3%81%A7%E4%B8%96%E7%95%8C%E5%B9%B3%E5%92%8C2014)
    - JavaScriptで魂を震えさせよう2015
- 基本的にはChromiumに実装されているAPIだったら諸々利用可能
    - WebGL
    - GamePad
    - FileReader
    - etc

# Electronを書いてみる前に知っておきたいこと

## must

- HTML / CSS / JS の最低限の文法など

## should

- HTML / CSSでの表現力
    - ここが見た目を左右するぞ
- NodeJSでの開発の知見
    - 便利npmモジュールなどを知っていると良い
- フロントエンド開発の知見
    - ページ遷移をチマチマやっても良いが大体loadingでモッサリする
    - →見た目をせっかくネイティブアプリっぽくしてるのにユーザーがガッカリする
    - Single Page Applicationである必要性
        - React/AngularJS辺りを検討することになる
    - 頑張ろう

## better but very important

- バグの切り分け（ちゃんと調べる）力
    - このバグはあなたのJSのバグですか？
        - Chromiumベースなので、Chromiumと同じDeveloperToolとかが使える
    - このバグはnpmモジュールのバグですか？
        - 怪しいnpmモジュールのissueを確認しよう
    - このバグはChromiumのバグですか？
        - [Issues - chromium - An open-source project to help move the web forward. - Google Project Hosting](https://code.google.com/p/chromium/issues/list)でそれっぽいbugが報告されていないか確認しよう
    - このバグはElectronのバグかも？
        - Electronのissueに報告されているかも？
            - https://github.com/atom/electron/issues

# Electronを始めよう

## 概要を把握したい

- とにかく https://github.com/atom/electron/tree/master/docs を読む。
- サンプルアプリケーションを読みたければ
    - https://github.com/electronjs/electron-sample
    - https://github.com/benogle/curve-app
    - https://github.com/atom/atom

## 環境構築

- NodeJS + npm をインストール
- `npm install -g electron-prebuilt`
    - これで`electron`コマンドで開発中のアプリケーションをとりあえず起動できる

## 世界観

- main process
    - 経緯からbrowser processと書かれていることもある
    - `package.json`の`main`を動かす
    - ここから各種GUI操作を呼び出す
        - `tray`を出す
        - `BrowserWindow`を作る
- renderer process
    - WebPage(HTML)を表示するためのChromiumが走ってるprocess
    - 通常のChromiumと違うのはNodeJSのAPIが利用可能

### 要約

- main process
    - `BrowserWindow`を作る
- renderer process
    - 作られた`BrowserWindow`がそれぞれ乗ってる

### 2つのプロセス間の通信

- 基本は`ipc`モジュールを使ってメッセージング
- `remote`モジュールを使うことで、renderer processでは利用できない`app`モジュールなどを呼び出すことも可能
    - 例

```js:render.js
const app = require('remote').require('app')
const path = app.getAppPath()
```

### devDependency

Electron開発をする場合はこの辺りをとりあえず揃えておくと良いと思う。livereload系とかはお好みで。

- `electron-compile`
    - ES6 / ES7 / JSX via Babel
    - TypeScript / CoffeeScript
    - LESS
- `electron-prebuilt`
    - `electron`コマンドの導入
- `electron-jasmine`
    - specs
- `electron-packager`
    - package化する部分をやってくれる

## Electron APIs

### Modules for the Main Process:

- [app](https://github.com/atom/electron/edit/master/docs/api/app.md)
- [auto-updater](https://github.com/atom/electron/edit/master/docs/api/auto-updater.md)
- [browser-window](https://github.com/atom/electron/edit/master/docs/api/browser-window.md)
- [content-tracing](https://github.com/atom/electron/edit/master/docs/api/content-tracing.md)
- [dialog](https://github.com/atom/electron/edit/master/docs/api/dialog.md)
- [global-shortcut](https://github.com/atom/electron/edit/master/docs/api/global-shortcut.md)
- [ipc (main process)](https://github.com/atom/electron/edit/master/docs/api/ipc-main-process.md)
- [menu](https://github.com/atom/electron/edit/master/docs/api/menu.md)
- [menu-item](https://github.com/atom/electron/edit/master/docs/api/menu-item.md)
- [power-monitor](https://github.com/atom/electron/edit/master/docs/api/power-monitor.md)
- [power-save-blocker](https://github.com/atom/electron/edit/master/docs/api/power-save-blocker.md)
- [protocol](https://github.com/atom/electron/edit/master/docs/api/protocol.md)
- [session](https://github.com/atom/electron/edit/master/docs/api/session.md)
- [web-contents](https://github.com/atom/electron/edit/master/docs/api/web-contents.md)
- [tray](https://github.com/atom/electron/edit/master/docs/api/tray.md)

### Modules for the Renderer Process (Web Page):

- [ipc (renderer)](https://github.com/atom/electron/edit/master/docs/api/ipc-renderer.md)
- [remote](https://github.com/atom/electron/edit/master/docs/api/remote.md)
- [web-frame](https://github.com/atom/electron/edit/master/docs/api/web-frame.md)

### Modules for Both Processes:

- [clipboard](https://github.com/atom/electron/edit/master/docs/api/clipboard.md)
- [crash-reporter](https://github.com/atom/electron/edit/master/docs/api/crash-reporter.md)
- [native-image](https://github.com/atom/electron/edit/master/docs/api/native-image.md)
- [screen](https://github.com/atom/electron/edit/master/docs/api/screen.md)
- [shell](https://github.com/atom/electron/edit/master/docs/api/shell.md)

## 開発時のTipsなど

- tmuxのcontextで起動すると日本語入力などがバグったりする
    - http://qiita.com/itkrt2y/items/dee87c406617d1bd45a6
- `app.dock.hide()`などOSXでしか動かないAPIを他の環境で叩くと当然のように落ちる
- `browserWindow.hide()`ではなく`browserWindow.quit()`を叩いてWindowの数が0になるとアプリケーションが終了する
- `tray`モジュールを使う場合はGCに注意
    - サンプルのとおりにやれば大丈夫

```js
var appIcon = null; //  この宣言をapp.onの中でやってしまうとGCに回収されたタイミングでtrayのアイコンが消滅する
app.on('ready', function(){
  appIcon = new Tray('/path/to/my/icon');
  var contextMenu = Menu.buildFromTemplate([
    { label: 'Item1', type: 'radio' },
    { label: 'Item2', type: 'radio' },
    { label: 'Item3', type: 'radio', checked: true },
    { label: 'Item4', type: 'radio' }
  ]);
  appIcon.setToolTip('This is my application.');
  appIcon.setContextMenu(contextMenu);
});
```

## 合わせて読みたい

- [Real World Electron Development - Qiita](http://qiita.com/mizchi/items/2bf64eb51d2018fa8a6a)