NW.jsでデスクトップアプリの夢を見る！

はじめに
=======
僕はNode.js製の[こんなソフト](http://minimum-opus.blog.jp/archives/11222272.html)を開発しているのですが、このソフトをユーザーの方に使っていただくには...

 - ユーザーにNode.JSをインストールしてもらわないといけない
 - 設定ファイルにパスワードがべた書きでセキュリティに不安がある
 - そもそも導入長ぇ！

...と、到底使ってもらえそうなものではありません。

そこで今回は、

 - ユーザーにNode.JSをインストールしてもらわないといけない
 - 設定ファイルにパスワードがべた書きでセキュリティに不安がある

を解決するためにNW.jsを使ってネイティブアプリ化をしていきます！

NW.jsとElectronの比較
=====================
NW.jsとは、JavaScriptを用いてWindows上で動作するアプリケーションを実装できるフレームワークです。似たようなものではElectronがVisual Studio Codeなどでも利用されており、こちらのほうが有名ですね。

では、何故今回NW.jsを選んだのかをElectronと比較しながら解説します。

Windowsアプリ化する手間の違い
----------------------------
Electronの場合はウィンドウのインスタンス生成をプログラムで記述する必要があります。つまり原理的にはヘッドレスなネイティブアプリも実装できます。C言語など他言語では当たり前の手法ですね。

一方で、NW.jsではエントリポイントにHTMLを指定して、HTMLファイルのscriptタグから実行コードが呼ばれます。
つまり、NW.jsでは必ず、ウィンドウ画面が生成・表示されます。
(...と書きましたが、最近はNW.jsでもNode.jsのソースファイルをエントリポイントにする方法はあるようです。)

Node.JSソースの実装方法の違い
---------------------------
ElectronはNode.JSと画面側は疎結合な関係で、生成された画面をNode.JSから操作することはできません。ですが、ウィンドウ自体はNode.JSから最初っから面倒を見ることができます。

一方、NW.jsはウィンドウ内のHTMLファイル側にNode.jsの実装も記載しますので、Node.JSと画面は密結合な状態になります。また、HTMLファイルがエントリポイントなので、少しカスタマイズは面倒くさそうな雰囲気です。

NW.jsを導入しよう！
===================
「公式サイトからダウンロードしないといけない」、「いや、npmでいける」などいろいろな情報が出てきますが、今回はnpmを使って導入することにしました！

※以下は、すでにあるプロジェクトに導入する前提で解説しています。

1. package.jsonを書き換える。
----------------------------
`main`セクションに`server.js`などと「*.js」が記載されていると思いますが、これを`index.html`と書き換えます。

次に`scripts`セクションに`"start": "nw"`の記述を追加します。もし先客がいる場合は、先客側の行末に「`,`」を追加して分割してください。

ここまでできれば、`package.json`は保存して閉じてください。

2. nwをインストールする
-----------------------
普通のnpmモジュール同様に、`npm install --save nw`コマンドでNW.jsをインストールします。

NW.jsを使ってみる！やっぱり最初は「Hello world!」
===============================================
NW.jsのインストールができたので、次はエントリポイントとなる「`index.html`」を作成して、とっとと画面を出してしまいます。以下は凄くシンプルな`index.html`の例

```html:index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>はろーわーるど！</title>
    </head>
    <body>
        <h1>はろーわーるど！</h1>
        <span>Node.JSバージョン: </span>
        <script src="外部ファイル.js"></script>
        <script>
            document.write(process.version);// Node.JS使えるよ！
        </script>
    </body>
</html>
```
※上記内「外部ファイル.js」は例ですので、いらない場合は`script`タグごと消してください。

そして`npm start`コマンドを実行すると...
![2a905b6f.png](https://qiita-image-store.s3.amazonaws.com/0/278909/16167ee7-1724-1b82-1da6-ca3463fe6fe2.png)
＼はろーわーるど！／＼はろーわーるど！／＼はろーわーるど！／

**てかめっちゃ簡単だった...正直びっくり！**

NW.jsの本領！～ビルドして実行ファイル化、ソースコードを秘匿化する(はず)
==================================================================
☆追記☆
--------
**この方法では完全にはソースコードやリソースファイルを保護することはできません。**詳細は[こちら](http://minimum-opus.blog.jp/archives/11453024.html)
1. ディレクトリ構造の変更
-----------------------
存在するプロジェクトに追加したのですが、もし、NW.jsで使えるようなディレクトリ構造になっていなければ、ディレクトリ構造を変更する必要があります。

僕のソフトの例では...
![2d8962d9.png](https://qiita-image-store.s3.amazonaws.com/0/278909/47f9f168-adcf-6f6b-77f1-b4f8a592b48d.png)
上記のように、「`index.html`」や、「`mailToKindle.js`」(TypeScriptのビルド後のファイル)、「`***.css`」などの実装のファイルがプロジェクトのルートフォルダにいらっしゃいます。
この場合、
![6b043bea.png](https://qiita-image-store.s3.amazonaws.com/0/278909/1108f9d6-cf2d-f67c-3cec-44b579ef0d24.png)
上記のように「`src`」などのフォルダにまとめる必要があります。

2. ウィンドウなどの設定を記述
---------------------------
`src`フォルダの中に**も**`package.json`を作成し、以下のように記述します。

```json:package.json
{
    "name": "はろーわーるど！！",
    "version":"1.0.0",
    "main": "index.html",
    "window": {
        "resizable": false,
        "show_in_taskbar": true
    }
}
```

3. nw-builderをインストールする
-----------------------------
NW.js本体と同様に、`npm install --save nw`コマンドでnw-builderをインストールします。

4. プロジェクトのルートディレクトリのpackage.jsonを編集する
-------------------------------------------------------
`scripts`セクションに`"build": "-p win32,win64 -o build/ src/"`の記述を追加します。今回は少なくとも`nw`がいるので、`nw`の行の行末に「`,`」を追加して分割してください。

また、ついでに`main`セクションの「`index.html`」は移動していますので、「`src/index.html`」に書き換えておきましょう。

5. いざビルド！
--------------
コマンドプロンプトにて`npm build`コマンドを実行し、ビルドします。
これで「`build`」ディレクトリ配下に実行ファイルやらいろいろ生成されているはずです！

締め
====
これでついにexeファイルを生成することができたので、**Node.JSのインストールなどの作業がユーザーはしなくて良くなりました！**
多分ゲームなどはこのくらいで配布して問題ないレベルかなと思います！

僕が作ったソフトがユーザーフレンドリーになる日は来るのか...！？

...続く！