今回はWindows、OS X、Linuxで動作するクロスプラットフォームなデスクトップアプリを開発するためのフレームワークを取り上げる。
powered by Insider.NET
前回はMVCフレームワークを三つ取り上げた。今回はJavaScriptでクロスプラットフォームなデスクトップアプリを開発するためのフレームワークを見てみよう。
本稿で見ていくフレームワークは以下の二つだ。
Node.jsにはサーバーサイドでJavaScriptを使用して、高速なWebアプリを開発するために必要な要素が詰まっているが(この辺りの事情については少々古い記事になるが『サーバサイドJavaScriptの本命「node.js」の基礎知識 』などを参考にしてほしい。基本は変わっていない)、これをクライアントサイドでも活用してネイティブデスクトップアプリを開発するための技術がElectronとNW.jsになる。
また、これらはChromium(簡単にいえば、グーグルのChromeのベースとなるオープンソースなWebブラウザー)と組み合わせて、WebページをUIに持つアプリを構築することで、Chromiumが動作するWindows、OS X、Linuxでクロスプラットフォームにアプリを実行できるようにしている。
クロスプラットフォームと聞くと、Windows/iOS/Androidの世界の話のような気もするがそうではなく、これらはデスクトップアプリまでもWeb標準技術でクロスプラットフォームに動かそうというお話である。なお、今回はインストール方法などについては割愛する。個々のページの説明を参照されたい(本稿ではnpm経由でインストールしている)。
ElectronはGitHubが開発しているオープンソースなフレームワークだ。以前は「Atom Shell」という名前で知られていた。これを使用したアプリも数多く存在している。本フォーラムでも取り上げているVisual Studio CodeはElectronを使用していることでもよく知られている。
Electron自体はあくまでも、Web標準技術でデスクトップアプリを開発するためのフレームワークなので、実際にはNode.js用の各種モジュールと組み合わせて、Webアプリを作る要領でデスクトップアプリを開発していくことになるだろう。
Electronの「Quick Start」ページにある最小限のElectronアプリ(を改変したもの)を以下に示す。最小限のElectronアプリは、package.jsonファイル(アプリの構成を記述)、JavaScriptファイル(アプリのロジックやUI制御コードを記述)、HTMLファイル(アプリのUIを構成)の三つで構成される。
{
"name" : "your-app",
"version" : "0.1.0",
"main" : "main.js"
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
</html>
var electron = require('electron');
var app = electron.app;
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null;
app.on('window-all-closed', function() {
app.quit();
});
app.on('ready', function() {
mainWindow = new BrowserWindow({width: 800, height: 600});
mainWindow.loadURL('file://' + __dirname + '/index.html');
mainWindow.on('closed', function() {
mainWindow = null;
});
});
package.jsonファイルでは、このアプリの名前とバージョン、エントリポイントを記述している。ここではエントリポイントはmain.jsファイルとなっている。
HTMLファイル(index.htmlファイル)の<script>タグ内部では、「process.versions.node」のようにNode.jsの提供するAPIを利用している。それ以外には特に説明の必要はないだろう。
JavaScriptファイル(main.jsファイル)でやっていることをまとめると、Electronを導入して、全てのウィンドウが閉じられたらアプリを終了するように設定し(app.quitメソッド呼び出し)、Electronの初期化が完了したら(「app.on('ready', ……」)ウィンドウを作成して、そこにindex.htmlファイルの内容を読み込んでいる。
これを実行すると次のような画面が表示される。
ここで重要になるのが、Electronにはメインプロセスとレンダラープロセスの2種類のプロセスがあることだ。
メインプロセスはOSにネイティブなGUIの管理やレンダラープロセスの起動、アプリ全体のライフサイクル管理を行う。レンダラープロセスは、個々のWebページを表示する。ざっくりとまとめると、メインプロセスとは「アプリの構成を記述するpackage.jsonファイルでmain属性に指定されたJavaScriptファイル(上の例ではmain.jsファイル)を実行するプロセス」のことだ。そして、そこから上のコードサンプルにあるように「new BrowserWindow(...)」を実行することでレンダラープロセスが生成される。
レンダラープロセスからはネイティブなGUI(とはメニューやダイアログなどのことだ)を自由に操作できないようになっているが、これはセキュリティおよびリソースリークの危険を考慮してのことである。ただし、メインプロセスとレンダラープロセスの間ではプロセス間通信が可能なため、これを利用してレンダラープロセスからメインプロセスにGUI操作を要求することは可能だ(後述)。
と書いたところで、あまり理解も進まないと思うので、以下では前回にチラリとお見せしたAngularJSを利用したWebアプリコードをElectronアプリ化してみよう。
AngularJSアプリをElectronアプリ化というと何やら大変そうだが、元が数行のコードしかないので、AngularJS側のコードは改変することなくElectronアプリにできた(が、実際にはそこまで簡単ではないだろう)。以下にコードを示す。今度はmain.jsファイル以外に、AngularJSコードを含むapp.jsファイルが必要になる。
まずはindex.htmlファイルと対応するAngularJSコードだ。
<!DOCTYPE html>
<html ng-app="myapp">
<head>
…… 省略 ……
<script src="js/angular.min.js"></script>
<script src="js/app.js"></script>
</head>
<body>
…… 省略 ……
<div ng-controller="FooController as fooctrl">
<p>
<input type="text" ng-model="fooctrl.test" />
{{ fooctrl.test }}
</p>
</div>
</body>
</html>
var app = angular.module('myapp', []);
app.controller('FooController', function() {
this.test = "foobar";
});
これは双方向バインドを使用して、テキストボックスに入力された値をリアルタイムでその隣に表示するだけのアプリだ。この状態ではElectronの要素は何ら存在していない。
エントリポイントとなるmain.jsファイルを以下に示す。実は先ほどのmain.jsファイルとほとんど変わっていない(変数名が変わったくらいだ)。
var electron = require('electron');
var app = electron.app;
var BrowserWindow = electron.BrowserWindow;
var mainWnd = null;
app.on('window-all-closed', function() {
app.quit();
});
app.on('ready', function() {
mainWnd = new BrowserWindow({width: 800, height: 600});
mainWnd.loadURL('file://' + __dirname + '/index.html');
mainWnd.on('closed', function() {
mainWnd = null;
});
});
これを実行すると次のようになる。
正直、AngularJSを使っただけで、説明することは特に増えていない。が、Electronを使うと(恐らくは)比較的容易にWebアプリのデスクトップアプリ化が実現できることが予想できると思う。しかも、これがWindowsでもMacでもLinuxでも動作するというのはなかなか魅力的だ。
Copyright© Digital Advantage Corp. All Rights Reserved.