NW.jsもまたNode.js、Chromium、Web標準技術を使用してクロスプラットフォームなデスクトップアプリを開発するためのオープンソースなフレームワークだ(Intel Open Source Technology Centerで誕生した)。以前は「node-webkit」と呼ばれていた。また、誕生したのはElectronよりも先で、すでに多くのデスクトップアプリが開発されている。
Electronのときと同じく、まずはAngularJSを使用したWebアプリをNW.jsアプリ化してみよう。といっても、今回も元のコードにはほとんど手を加えていない。なお、ElectronではアプリのエントリポイントはJavaScriptファイルとなっていたが、NW.jsではHTMLファイルをエントリポイントとするのが一般的だ(JavaScriptファイルをエントリポイントとすることも可能なようだ)。
そのため、package.jsファイルは以下のようになる。
{
"name": "nwjs-test",
"main": "index.html"
}
HTMLファイルとJavaScriptファイルについては、冒頭に示したものと同様なので省略しよう。これを実行すると次のような画面が表示される。
ウィンドウの外枠こそ違うが、Electronアプリと同様にさっくりとデスクトップアプリ化できた。
ただし、このままではNW.jsのパワーは全く使っていない(最初のElectronアプリでElectronコードが全く使われていなかったのと同じだ)。そこで、ありがちだが、index.htmlファイルの中からNW.js(というか、Node.js)の機能を使用してみよう。
<!DOCTYPE html>
<html ng-app="myapp">
…… 省略 ……
<body>
…… 省略 ……
<script>
var os = require('os');
document.write("platform: " + os.platform());
</script>
</body>
</html>
このように<script>タグ内部でもrequire関数の呼び出しが可能だ。これは、NW.jsはウィンドウが作成されるときにNode.jsのコンテキストに存在するglobalオブジェクトのメンバー(require関数など)を、そのウィンドウのWebのコンテキスト(windowオブジェクト)に移設するからだ。このとき、実際にはrequire関数はNode.jsのコンテキストで呼び出され、その結果がWebコンテキストに返送されることになる。
NW.jsのコンテキストは便利な面、コンテキストを意識する必要があり、慣れないと困惑を招く場合もある。詳細が気になる人は「Transfer objects between window and node」ページを参考に実際にコードを書きながら挙動を試してみるのがよい。
また、globalオブジェクトは複数のウィンドウ間でも共有される。これを活用することで、ページ間での情報を受け渡しがとても簡便な形で行える。が、グローバルな変数の値はいつどこで誰が書き換えるかは分からない。使いすぎには注意しよう。
と言いながら、NW.jsのサンプルの最後として、globalオブジェクトの使用例を示す。index.htmlファイルに以下のようにボタンを追加して、そのハンドラーをFooControllerクラスに追加する。
<!DOCTYPE html>
<html ng-app="myapp">
…… 省略 ……
<body>
…… 省略 ……
<div ng-controller="FooController as fooctrl">
<p>
…… 省略 ……
</p>
<button ng-click="fooctrl.go2ndpage()">go 2nd page</button>
</div>
</body>
</html>
app.controller('FooController', function() {
this.test = global.test || 'foobar';
this.go2ndpage = function() {
global.test = this.test;
window.location.href = 'secondwin.html';
};
});
実際には、これと同様な構造のHTMLファイル(secondwin.htmlファイル)とJavaScriptファイル(sub.jsファイル)を用意している。
ボタンがクリックされると、そのハンドラーでは「global.test」変数に「tehis.test」変数の値をセットして、secondwin.htmlファイルの内容を読み込む。すると、secondwin.htmlファイルが読み込んだsub.jsファイルではglobal.test変数の値を使ってテキストボックスが初期化されるわけだ(「this.test = global.test || 'foobar';」行。global.test変数がなかった場合には"foobar"が初期値として使われるようにしてある)。
これを実行すると、次のようになる。
ここでは複数ウィンドウではなく、単一ウィンドウでページ遷移をする形のアプリとなっているが、globalオブジェクトを利用して情報を受け渡せているのが分かる。乱用はまずいが、時と場合によっては便利に使えるだろう。
ここまで、ElectronとNW.jsについて簡単に見てきた。どちらもクロスプラットフォームなデスクトップアプリを開発するためのフレームワークであるが、その構成は意外と異なっている。
「Technical Differences Between Electron and NW.js」ページでは、これら二つのフレームワークの技術的な差異について述べられている。簡単にまとめると次のようになる。
本稿で見てきたことを中心にまとめるとおおよそ次のようになる。
この他にも、インストーラーや自動アップデートなど、さまざまな面で相違点がある。興味のある方は上記のページや「NW.js & Electron Compared」ページを参考にしてほしい。
Copyright© Digital Advantage Corp. All Rights Reserved.