electron 上で vue.js を動かす

概要
====

node.js も vue.js も初心者のプログラマが、electron 上で vue.js を動かす方法を紹介するだけの記事です。
プラットフォームは Windows7、node.js のバージョンは 6.10.2、vue のバージョンは 2.3.2 で書きました。


準備
====

## node.js のインストール

[公式サイト](https://nodejs.org/ja/)からダウンロードとインストールを行います。コマンドプロンプトで

```
> node -v
v6.10.2
```

と打って、バージョン番号が表示されたら成功です。

## パッケージのインストール（グローバル）

`npm` コマンドを使い、electron-prebuilt と webpack をインストールします。
ここでは `-g` オプションを付けて、グローバルインストールを行っています。

```
> npm install electron-prebuilt -g
> npm install webpack -g
```

この処理には少し時間がかかります。ちゃんとインストールできたかどうかは、

```
> npm ls -g --depth=0
```

で出てくるリストを見れば分かるでしょう。（`--depth=0` は表示範囲を絞るためのオプションです）

アプリケーションの作成
====================

## プロジェクトの作成

良さそうな場所に `mkdir` でプロジェクト用のディレクトリを掘ります。
ここでは仮に `myelevue` という名前にしておきます。

```
> mkdir myelevue
> cd myelevue
```

## package.json の作成

上で作成した `myelevue` ディレクトリをカレントとして、次のコマンドを実行します。

```
> npm init
```

色々と質問されますが、特にこだわりが無ければエンターキー連打で構いません。
これで `package.json` というファイルが作られるので、テキストエディタで開きます。
このファイルには先ほどされた質問への回答が保存されています。ここに、次の要素を加えます。

```json:package.json
{
  ...
  "private": true,
  ...
}
```

こうしておくと、次にパッケージのローカルインストールを行った際に警告されずに済みます。
なお、上記コードの `...` の部分は省略です。入っている値はそのままにしておいて下さい。
（json ファイルの記法に詳しくない場合は調べましょう）

## パッケージのインストール（ローカル）

やはり `myelevue` がカレントだとして、次のコマンドを実行します。

```
> npm install vue --save
```

`-g` オプションを付けていないためカレントに `node_modules` というディレクトリが作られ、
その中にパッケージが入ります。また、`--save` オプションを付けたことで `package.json` に
このパッケージをインストールしたことが記録されます。

なお、上で `package.json` に `"private": true` を書き加えなかった場合、

```
npm WARN myelevue@1.0.0 No description
npm WARN myelevue@1.0.0 No repository field.
```

といった警告が出ます。きちんとこれらの項目を埋める方が行儀が良いかもしれません。

## app.js の作成

`myelevue` ディレクトリの子として `src` ディレクトリを掘り、そこに `app.js` を作ります。

```javascript:src/app.js
import Vue from 'vue';

var vm = new Vue({
  el: '#sample',
  data: {
    message: 'Hello, World!!'
  }
});
```

## webpack.config.js の作成と webpack の実行

ここでは webpack を使い、動作に必要なスクリプトを一つのファイルにまとめます。
そのための設定ファイル `webpack.config.js` を `myelevue` ディレクトリの直下に作ります。

```javascript:webpack.config.js
module.exports = {
  entry: './src/app.js',
  output: {
    path: `${__dirname}/html`,
    filename: 'packed.js'
  },
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
};
```

なお、`resolve` の部分については `node_modules/vue/dist/README.md` に記述があります。
記述に従って `vue.esm.js` を指定した場合は、ブラウザや electron のコンソールに
develop 版が動作している旨のメッセージが表示されます。

さて、ファイルを作ったら次のコマンドを実行します。

```
> webpack
```

上手くいけば、これで `html/packed.js` というファイルが作られます。
今後 `src/app.js` や `webpack.config.js` を書き換えたら、
その度に `webpack` コマンドを実行する必要があります。（自動化する方法もあるそうですが）

## index.html の作成

上で作成した `packed.js` を読み込んで動かすため、`html/index.html` を作ります。

```html/index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
</head>
<body>
  <div id="sample">
    <p>{{message}}</p>
  </div>
  <script src="packed.js"></script>
</body>
</html>
```

作ったら、ひとまずブラウザで開いてみましょう。
上手くいっていれば Hello, World!! と表示されるはずです。


## index.js の作成と electron の実行

後は electron で動くようにするだけです。
`myelevue` の直下に、`index.js` という名前でファイルを作ります。
（ここは `package.json` の `"main"` の値に合わせる必要があります）

```javascript:index.js
'use strict';

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

var mainWindow = null;

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

app.on('ready', function() {
  mainWindow = new BrowserWindow({
    width: 1280,
    height: 720
  });
  mainWindow.loadURL(`file://${__dirname}/html/index.html`);
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});
```

ここまでできたら、次のコマンドを実行します。

```
> electron .
```

単なる `electron` ではなく `electron .` と引数に `"."` が与えられているので注意しましょう。
ウィンドウが開き、ブラウザで見た時と同様に Hello, World!! と表示されていれば成功です。

最後に
======

結構な数のファイルを作成したので、ここで構造をまとめておきます。

```
myelevue
|   index.js
|   package.json
|   webpack.config.js
|
+---html
|       index.html
|       packed.js
|
+---node_modules  （※この中身は省略）
|               
\---src
        app.js
```

ググって出てくる資料とは node.js や vue.js の仕様が微妙に変わっていて動かない！
という目に遭ったため、自分でもまとめてみました。（数年したら、これも動かなくなるのかもしれません）

色々なパッケージを使っていますがほぼ見様見真似なので、
もし勘違いや致命的におかしな使い方をしている箇所があればご指摘頂けると幸いです。