NW.jsとElectronをしばらく使ってみての比較

既存のwebサイトをお手軽にWindowsアプリケーションにするという目的で、しばらくNW.js(0.12)とElectronをいじってみての印象です。

※Windows7(x64)上で実行しています
※NW.jsはVer.0.12.3、ElectronはVer.0.35.06を使用しています

##NW.jsはpackage.jsonを書くだけでアプリ化できる
NW.jsはpackage.jsonのmainオプションにURIを指定するだけでWindowsアプリ化することができる。
Electronは必ず「ウィンドウを開く」処理を書く必要がある。

##ブラウザウィンドウのデフォルトフォント
###NW.js
デフォルトではcjkフォントになってしまう。フォントを指定するインターフェースなし。
アプリ化したいサイトが適切なfont-familyの指定をしていなかった場合、[Window.open](http://docs.nwjs.io/en/v0.13.0-beta4/References/Window/#windowopenurl-options-callback)時の`inject-js-end`オプションで`*{font-family:"適当なフォント"}`とかを流し込まないといけない。
###Electron
[ウィンドウ作成時のオプション](http://electron.atom.io/docs/v0.36.5/api/browser-window/#new-browserwindowoptions)で、デフォルトフォントを指定できる。

##\<script\>タグで使用できる機能
###NW.js
htmlファイルのscriptタグ内で、node.js、NW.jsライブラリすべてに触ることができる。

```html:NW.jsならこんなこともできる
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <script>
            var fs = require('fs');
            var fileContent = fs.readFile(somefile, someFunction);
        </script>
    </head>
```
###Electron
メインプロセス、レンダープロセスでできる機能が厳密に分化されており、レンダープロセスからnode.jsの機能は使用できない(loadURLで読み込まれたhtmlファイル内の\<script>タグのJavascriptはレンダープロセスで動く)。
なお`remote`モジュールを使用してメインプロセス内のモジュールを呼び出したり、`ipc`(プロセス間通信モジュール)を使用してメインプロセスに対してメッセージを送ったりできる。
これがなかなか便利。

##ウィンドウを開いた時、親から子ウィンドウのDOMに触れるか
NW.jsは触れる、Electronは触れない。
###NW.js
子ウィンドウのWindow.windowオブジェクトから、windowオブジェクトにアクセスできる。
###Electron
子ウィンドウのwindowオブジェクトにアクセスするためのインターフェースは用意されていない。

##Javascriptを埋め込んで実行する機能
NW.js、Electronともに、htmlを開く際に任意のJavascriptファイルを読み込んで実行させる機能がある。
これを使用することで、既存のwebページにkeydownイベントを追加し、独自のショートカットキーなんかを追加できる。**非常に便利**。

###NW.js
Window.open時の[inject-js-start, inject-js-endオプション](http://docs.nwjs.io/en/v0.13.0-beta4/References/Manifest%20Format/#inject-js-start)
読み込んだjsファイル内で、node.js、NW.jsのモジュール**使用不可**。
###Electron
new BrowserWindowの[preloadオプション](http://electron.atom.io/docs/v0.36.5/api/browser-window/#new-browserwindowoptions)
node.js、Electronのライブラリ**使用可**。
たとえBrowserWindowのオプションで`nodeIntegration:false`を指定していても使用できる。

##パッケージ化
###NW.js
パッケージ化が楽、かつ実行に必要なファイルが少なくてすっきりしている。
ソースとnode_modulesをzipで固め、nw.exeと連結するだけ。
※他にも実行に必要なファイルはあるが、Electronに比べてはるかに少ない。
https://github.com/nwjs/nw.js/wiki/How-to-package-and-distribute-your-apps#windows-1

###Electron
electron-packagerモジュールを使用してパッケージ化する。
しかし実行ファイルと同じディレクトリに、大量のDLLやらが必要。

```js
var app = require('app'); 
var BrowserWindow = require('browser-window'); 
var mainWindow = null;
app.on('window-all-closed', ()=> app.quit());
app.on('ready', function() {
    mainWindow = new BrowserWindow({width: 320, height: 200});
    mainWindow.loadURL('file://' + __dirname + '/index.html');
    mainWindow.on('closed', ()=> mainWindow = null);
});
```
上記のようなindex.htmlを表示するだけのプログラムでも、パッケージ化したファイルの実行には、下のような大量のファイルが必要…

```text
      15  content_resources_200_percent.pak*
    8.8M  content_shell.pak*
    4.0M  d3dcompiler_47.dll*
     70M  helloworld.exe*
    9.8M  icudtl.dat*
     13K  libEGL.dll*
    2.1M  libGLESv2.dll*
    1.1K  LICENSE*
    1.2M  LICENSES.chromium.html*
       0  locales/
    645K  msvcp120.dll*
    941K  msvcr120.dll*
    430K  natives_blob.bin*
     12M  node.dll*
     11M  pdf.dll*
       0  resources/
    643K  snapshot_blob.bin*
    103K  ui_resources_200_percent.pak*
    349K  vccorlib120.dll*
       7  version*
    105K  xinput1_3.dll*

```
※[Enigma Virtual Box](http://enigmaprotector.com/en/aboutvb.html)等を使えば、実行ファイルを1つにできるが、動作が少し遅くなる。

##ElectronはES6の文法が使える
NW.jsはpackage.jsonのjs-flagsを指定すれば可能。

##NW.jsはJQueryを問題なく読みこめる
Electronは`new BrowserWindow`時のオプションに`nodeIntegration: false`が必要。
**ただし[zepto.js](http://zeptojs.com/)のようなのJQuery互換ライブラリを使えば問題ない**。

#現状の結論
既存のwebサイトをアプリ化するだけならNW.jsの方が楽ですが、そこにJavascriptを流し込んで機能を追加したりしたいならElectronの方が扱いやすい、という印象です。
またWebサイトのアプリ化ではなく、(クロスプラットフォーム)アプリケーション開発という目的で使用するのであれば、ipcが使え、ライブラリでダイアログオープンを持つElectronの方が開発しやすそうに感じます。