RaspberryPi起動時にmatchbox-window-managerとelectronを同時に起動したい場合にどうしたか

# 環境
・Macos Mojave
・ラズパイイメージ：2019-04-08-raspbian-stretch-lite.img
http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian_lite/images/raspbian_lite-2019-04-09/
↑からダウンロードできそうです。（2019-04-08-raspbian-stretch-lite.zip）

# 前提
ラズパイで必要な初期設定は済ませておきましょう
・SSHの有効化
・apt-get update
・apt-get upgrade

# まずはMac側でelectronアプリを用意

### package.jsonつくる
`npm install`後にpackage.jsonを一部修正します。
修正箇所は`"main": ".index.js",`の部分を今回の構成用に`"main": "./app/src/index.js",`に修正します。

```console
$ npm init
$ npm install electron -save
```

```json
{
  "name": "test-electron",
  "version": "1.0.0",
  "description": "",
  "main": "./app/src/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "electron": "^6.0.10"
  }
}

```

### htmlとjsつくる
app/src/index.js

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

let mainWindow = null;

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

app.on('ready', function() {

  mainWindow = new BrowserWindow({
    width: 800
    , height: 600
    , webPreferences: {
        nodeIntegration: true
    }
  });
  
  mainWindow.loadURL('file://' + __dirname + '/../../app/view/index.html');
  mainWindow.setFullScreen(true);
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});
```

app/view/index.html

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<h1>テストアプリ</h1>
</body>
</html>
```

### できたディレクトリ構成がこちら

```console
$ tree
.
└── test-electron
    ├── app
    │   ├── src
    │   │   └── index.js
    │   └── view
    │       └── index.html
    └── package.json

4 directories, 3 file
```


# 次にラズパイ環境を整備する

### まずは、matchbox-window-managerをインストール

```console
$ sudo apt-get install -y xinit matchbox-window-manager
```

### matchbox-window-managerだけだと、動かないので、xtermもいれる
```console
$ sudo apt-get install -y xterm
```

### matchbox-window-managerを起動

```console
$ sudo xinit matchbox-window-manager


X.Org X Server 1.19.2
Release Date: 2017-03-02
X Protocol Version 11, Revision 0
Build Operating System: Linux 4.9.41-v7+ armv7l Raspbian
Current Operating System: Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l
Kernel command line: 8250.nr_uarts=0 bcm2708_fb.fbwidth=576 bcm2708_fb.fbheight=416 bcm2708_fb.fbswap=1 vc_mem.mem_base=0x3ec00000 vc_mem.mem_size=0x40000000  dwc_otg.lpm_enable=0 console=ttyS0,115200 console=tty1 root=PARTUUID=fe4a531f-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
Build Date: 18 October 2017  04:55:30PM
xorg-server 2:1.19.2-1+rpt1+deb9u2 (https://www.debian.org/support) 
Current version of pixman: 0.34.0
	Before reporting problems, check http://wiki.x.org
	to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
	(++) from command line, (!!) notice, (II) informational,
	(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/Xorg.0.log", Time: Tue Sep 24 07:02:54 2019
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
```

### node.jsを使えるようにする

```console
$ sudo apt-get install -y nodejs npm
```
このままだと、古いバージョンのnodeが入ってしまうようなので、nodeをバージョンアップします。

```console
$ sudo npm install npm n -g
$ sudo n stable sudo n stable
```
このままだと、
バージョンに変化がないので、ログアウトして、再度sshしてみると、最新バージョンに切り替わってます。


### chromium-browserをインストールする
electronを動作させるために必要な関連モジュールをインストールしますが、この場合chromium-browserをインストールすることで、全てまかなえます。

```console
$ sudo apt-get install -y chromium-browser
```


# アプリも、環境もできたので動かしてみる

### まずは、Macからラズパイへsftpでファイル送信する
圧縮して、送信して、を行います。
ここでは、node_modulesフォルダを含めず、かつ権限情報を含めない形でtar.gz化します。

```console
$ tar cvfz test-electron.tar.gz --no-same-owner --no-same-permissions --exclude node_modules test-electron
$ sftp pi@{ラズパイのIPに読み替えて}
Connected to pi@{ラズパイのIPに読み替えて}.
sftp> put test-electron.tar.gz
Uploading test-electron.tar.gz to /home/pi/test-electron.tar.gz
test-electron.tar.gz                                                                                                                                                100%  839    42.8KB/s   00:00    
sftp> 
```

### ラズパイ内で解凍してからnpm installする
ラズパイ環境で動かすためには、ラズパイ環境下で`npm install`を実施する必要があるので、それを行ってください。

```console
$ cd ~
$ tar zxvf test-electron.tar.gz
test-electron/
test-electron/app/
test-electron/package.json
test-electron/app/view/
test-electron/app/src/
test-electron/app/src/index.js
test-electron/app/view/index.html
$ cd test-electron
$ npm install
npm WARN test-electron@1.0.0 No description
npm WARN test-electron@1.0.0 No repository field.

audited 201 packages in 5.49s
found 0 vulnerabilities
```

2つWARNでてますが、気になる方は、`npm init`の際にちゃんと入力してください！

### electron起動！
一点注意ですが、`sudo xinit matchbox-window-manager`を実行した状態のままにしておいてください！

↓ssh経由でコマンドうってる場合。

```console
$ DISPLAY=:0 node_modules/.bin/electron .
Fontconfig warning: "/etc/fonts/fonts.conf", line 100: unknown element "blank"
ATTENTION: default value of option force_s3tc_enable overridden by environment.
```

あ、フォント入ってない。。
フォント入ってないので、文字化けしますが、これで無事electronが起動できました。


# ここからが本題。
本記事は、「RaspberryPi起動時にmatchbox-window-managerとelectronを同時に起動したい場合にどうしたか」ですので、ここから起動時にmatchbox-window-managerとelectronを起動するように設定していきたいと思います。

## rc.localで制御する
/etc/rc.localのファイル内で、`exit 0`の手前に、起動コマンドかきます。

```
$ sudo vi /etc/rc.local

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

xinit matchbox-window-manager -- -nocursor &
su -l pi -c 'DISPLAY=:0 /home/pi/test-electron/node_modules/.bin/electron /home/pi/test-electron'
exit 0
```


## rebootして表示確認
ファイルの変更を保存して、`sudo reboot`で再起動してください。
これで起動時に作成したelectronアプリが表示されます！


# 少し補足

### npm installでWARNでてる件
ラズパイ環境でnpm installするって箇所で、現在WARNがでてますが、これはちゃんと取り除けます。

```console
$ 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>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (xxx) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 

```
`npm init`の際に、ちゃんとdescriptionとgit repositoryを入力しましょう。
また、package.jsonを手で書き換えることでも対処できます。


### matchbox-window-managerを起動する際のオプション
「rc.localで制御する」のときにしていしていた`-nocursor`オプションですが、これはデフォルトで表示されているマウスカーソルの表示を消すオプションになります。
不要な場合、`-nocursor`を消してrc.localに記述してください。

### npm install electron -save
electronをnpm install際に-saveオプションをつけてますがこれをつけることにより、package.jsonのdependenciesに自動的に追記してくれます。


# さいごに
今回、rc.localでラズパイ起動時にmatchbox-window-managerとelectronを同時に起動するように制御しましたが、他にもいろいろいい方法があるんじゃないかなぁと思ってますので、ご存知の方は是非コメント頂けると嬉しいです！