@angular/cliでElectron

#はじめに
極力手を抜いて@angular/cliからElectronアプリのベースを作りたいなぁ
## 構成
- @angular/cli 1.4.5
- electron 1.7.8

#angularの準備
## ng new
とりあえず「ng new」でプロジェクトを作ります。

```
$: npm install -g @angular/cli
$: ng new MyApp
$: cd MyApp
```

## ng eject
早速ですが、後でwebpackをいじらないといけないので「ng eject」します。

```
$: ng eject
$: yarn
```

ここまででangularは一旦置いてきます

#Electronの準備
## Electron追加
Electronをプロジェクトに追加します（アプリ上で呼び出すのでなんとなくdependenciesに入れています）。

```
$: yarn add electron
```

## ディレクトリ作成
今回はベースのみですが、将来的にビルド環境まで考えるとアプリ用にディレクトリを作っておいた方が良さそうなので「electron-app」というディレクトリを作成し、「src」ディレクトリを移動します。

```
$: mkdir electron-app
$: mv src ./electron-app/
```

## package.json
Electron用のpackage.json（プロジェクトとは別もの）を作成します。

```json:package.json
{
  "name": "MyApp",
  "version": "0.0.1",
  "author": "Mamoru Izuka",
  "license": "MIT",
  "description": "Angular + Electron App",
  "main": "electron.main.js"
}
```

## electron.main.js
Electron用JSファイルは、[Electron Quick Start](https://github.com/electron/electron-quick-start)から転用し、WebpackDevServer等に対応するため一部変更します。

```js:electron.main.js（変更前）
function createWindow() {
// =====================省略========================= //
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  }))
// =====================省略========================= //
}
```


```js:electron.main.js（変更後）
const PORT = process.env.PORT || 3000;

function createWindow() {
// =====================省略========================= //
  if (process.env.NODE_ENV === 'development') {
    console.log(`electron window load: http://localhost:${PORT}`);
    mainWindow.loadURL(`http://localhost:${PORT}`);
  } else {
    mainWindow.loadURL(url.format({
      pathname: path.join(__dirname, 'dist/index.html'),
      protocol: 'file:',
      slashes: true,
    }));
  }
// =====================省略========================= //
}
```

ここでElectronも一旦置いておきます。

#Webpack
##target: 'electron-renderer"
Electron用にコンパイルするようにtargetを指定します（何故cliのwebpack.config.jsはオブジェクトを文字列化してるんだろうか？）。

```js:webpack.confg.js
module.exports = {
// =====================省略========================= //
  "target": "electron-renderer",
// =====================省略========================= //
};
```

##各パスの修正
entryやmodule等のパスが「./src/~」となっているので「./electron-app/src/~」に全て修正します。

#細かな修正
##パスの修正
tsconfig.json等のパスも「./electron-app」ベースに修正が必要です。

#仕上げ
##server.js
webpack-dev-serverとelectronを同時起動するためにプロジェクトのルートディレクトリに「server.js」を書きます。

```js:server.js
const spawn = require('child_process').spawn;
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');

const conf = require('./webpack.config');
const PORT = process.env.PORT || 3000;

const compiler = webpack(conf);

const server = new WebpackDevServer(compiler, {
  hot: true,
  historyApiFallback: true,
  stats: {
    colors: true,
  },
});

server.listen(PORT, 'localhost', (err) => {
  if (err) {
    return console.error(err);
  }

  spawn('yarn', ['start-electron'], {
    shell: true,
    env: process.env,
    stdio: 'inherit',
  })
    .on('close', (code) => {
      process.exit(code);
    })
    .on('error', (err) => {
      return console.error(err);
    });

  return console.log('Webpack Dev Server Running at:' + PORT);
});
```

##package.json
上記を呼び出すためにプロジェクトの方のpackage.jsonにscriptを追加し、「start」コマンドも編集します。

```json:pacakge.json
    "start-electron": "electron ./electron-app",
    "start": "cross-env PORT=3000 NODE_ENV=development node ./server.js",
```

忘れてましたが、[cross-env](https://www.npmjs.com/package/cross-env)を使うのでインストールしておいてください。
```
$: yarn add --dev cross-env
```

#完成
##start

```
$: yarn start
```

でElectronが起動して「Welcome to app!」と表示されれば成功です。

#終わりに
あまり手軽感がない。

#追記
electron-appとディレクトリを切っていますが、このままelectronのmain.jsでnode_modulesを呼び出すと失敗します。electron-app内に別途node_modulesを作るか何かする必要があります。