NW.js
Electron

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

More than 3 years have passed since last update.

既存の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時のinject-js-endオプションで*{font-family:"適当なフォント"}とかを流し込まないといけない。


Electron

ウィンドウ作成時のオプションで、デフォルトフォントを指定できる。


<script>タグで使用できる機能


NW.js

htmlファイルのscriptタグ内で、node.js、NW.jsライブラリすべてに触ることができる。


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オプション

読み込んだjsファイル内で、node.js、NW.jsのモジュール使用不可


Electron

new BrowserWindowのpreloadオプション

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やらが必要。

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を表示するだけのプログラムでも、パッケージ化したファイルの実行には、下のような大量のファイルが必要…

      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等を使えば、実行ファイルを1つにできるが、動作が少し遅くなる。


ElectronはES6の文法が使える

NW.jsはpackage.jsonのjs-flagsを指定すれば可能。


NW.jsはJQueryを問題なく読みこめる

Electronはnew BrowserWindow時のオプションにnodeIntegration: falseが必要。

ただしzepto.jsのようなのJQuery互換ライブラリを使えば問題ない


現状の結論

既存のwebサイトをアプリ化するだけならNW.jsの方が楽ですが、そこにJavascriptを流し込んで機能を追加したりしたいならElectronの方が扱いやすい、という印象です。

またWebサイトのアプリ化ではなく、(クロスプラットフォーム)アプリケーション開発という目的で使用するのであれば、ipcが使え、ライブラリでダイアログオープンを持つElectronの方が開発しやすそうに感じます。