ふろしき Blog

インターネットビジネスの基本知識やWebテクノロジー、エンジニア組織論について、経験談を交えつつお話します

HTML5でクロスプラットフォームなデスクトップアプリを作る〜XULRunner〜

デスクトップ用途で最もシンプルかつオープン系なものは、XULRunnerではないでしょうか。

XULRunnerはMozillaのGeckoエンジンをランタイムとして利用しデスクトップアプリ化させる、90年代からある歴史あるOSS製品です。

Geckoは、HTML/JavaScript/CSSのようなオープンなWeb技術を動作させるものと思われがちですが、実はそうでもありません。XULやXPCOMといったクロスプラットフォームでアプリケーションを動かすためのエンジンを兼ね備えていて、デスクトップ用途だとこちらを推奨しているようです。

Firefox上でも、XULで作ったデスクトップアプリを動作させることが可能です。ただし、XULやXPCOMはMozilla限定なクローズドな技術です。HTML5でそこそこのアプリ表現能力を手にしたということもあり、今ならWeb技術のみで作るのがありではないかと思います。

XULRunnerは環境依存せず、Win環境下ではインストールレスで使えるため、アプリごとにランタイムとセットで配布することも可能です。Javaの場合、OS依りにバージョンが紐付きますが、XULRunnerはアプリ依りにできるのです。予期せぬアップデートのリスクからアプリを守ることができ、エンタープライズ系だと大きなメリットになるでしょう。ただし、Tridentほどサポートが充実していないのが弱点です。オープンソースなので、自力でメンテナンスする必要があります。

では早速、セットアップしてみましょう。

どうやってダウンロードするのか?

ここでダウンロードできます。ただ、少し注意が必要です。

f:id:furoshiki0223:20130918164401p:plain

XULRunnerのメジャーバージョンは、Geckoのバージョンと一致します。つまり、Firefoxの各メジャーバージョンと同じHTML5対応が行われていることになります。ただし、XULRunnerの最新バージョンは、Firefoxの安定版と同じになるとは限りません。少し時間差があります。なので、latest配下の資材を利用するのが良いでしょう。

latest配下には、「runtimes」「sdk」「source」の3つのディレクトリがありますが、今回利用するのはruntimesです。そしてruntimesの下には、

f:id:furoshiki0223:20130918164817p:plain

命名規則からもお分かり頂けると思いますが、Linux(32/64)、Win、Mac専用のランタイムが圧縮された状態で配置されています。設定ファイル自体にはそこまで大きな違いはないのですが、各環境OSごとに必要なライブラリは違いますので、OSごとに最小の構成が詰め込まれています。

ここでは、Windows用を試してみましょう。

設定ファイル

ダウンロード後のファイルを展開すると、色んなファイルが横並びに詰め込まれている「xulrunner」ディレクトリが配置されます。今回使うのは、この中にある「xulrunner.exe」のみです。

xulrunner.exeは、設定ファイルが無いと動きません。本来ならテンプレートも一緒に詰めておいて欲しいところですが、残念なことにそれは含まれていません。なので、自力で作る必要があります。

全体の構成を説明します。

f:id:furoshiki0223:20130918165445p:plain

chromeディレクトリには、デスクトップアプリ化させるためのXULやHTMLファイルが配置されます。直下でなく、「content」というディレクトリを一つ下に配置するのが一般的です。この下に、index.htmlやらcss/jsディレクトリを作るイメージになります。chromeという名前はついていますが、Webブラウザ「chrome」とは偶然被ったぐらいに思って下さい。

xulrunnerディレクトリは、ダウンロードしてきたものそのまま配置です。編集は不要です。

defaults/preferencesディレクトリには、Firefoxの「about:config」に相当するフラグを「prefs.js」にて設定します。この中に、アプリ起動時に最初に読み込むhtmlファイルを指定したりもします。

以下、そのサンプルです。

pref("toolkit.defaultChromeURI", "chrome://myapps/content/index.html");

pref("browser.dom.window.dump.enabled", true);
pref("javascript.options.showInConsole", true);
pref("javascript.options.strict", true);
pref("nglayout.debug.disable_xul_cache", true);
pref("nglayout.debug.disable_xul_fastload", true);

WebGLが必要であれば、ここで予めフラグを有効にする必要があるでしょう。

「application.ini」は、ブート設定が書き込まれており、xulrunner起動時に引数として渡します。以下がサンプルです。

[App]
Vendor=hiroshik
Name=myapps
Version=1.0
BuildID=20130917
Copyright=Copyright (c) 2013 hiroshik.info
ID=kawada.hirosi@example.com

[Gecko]
MinVersion=22.0
MaxVersion=400.*

注意すべき点として、Name属性の内容でしょう。Name属性は設定キャッシュの識別子みたいな役割を持つようで、設定変更時はNameも変えないと、新しい設定値が反映されないという動きをします。注意して下さい。

「chrome.manifest」も似たようなものです。

content myapps file:chrome/content/

XULRunnerの良くないと思っているところに、失敗時に黙って落ちるところです。設定がミスっていた場合に、どこにもログが図れること無く、黙って動作を終わらせてしまうのです。設定値を変えつつ、application.iniのname属性を変えつつみたいな進め方になると思います。

もしかしたら、もっと良い方法があるのかもしれませんが、私は見つけることができませんでした。

実行

実行は簡単です。

.¥xulrunner¥xulrunner.exe application.ini

実行すると、シンプルなウィンドウにHTMLで記述された内容がそのまま出力されるはずです。失敗すると、うんともすんとも言いません。

デスクトップアプリと違って、ウィンドウサイズが小さく表示できない部分も、スクロールバーの移動で見えるようにできるというメリットがあり、非常にポータブルです。

Webはネイティブを置き換えることができないという議論は、もう散々されてきたと思います。一応警告しておくと、この方法では完全なネイティブ置き換えはできません。ポータビリティとのトレードオフです。シンプルな画面のアプリ、Webっぽい画面のアプリで、なおかつネットワーク依存の弱いデスクトップアプリを作りたいというのであれば、オススメできる方法かと思います。

Geckoは古いPCでも動作できる作りなので、長期のライフサイクルでリスクヘッジの一つとして選択するのもありかもしれません。また、.NETとちがってバージョンが上がるごとに書き換えが必要なんてこともWebは少ないので、ソースコードの前方向への互換性は強いかと思います。

ただ、Webはサポートがあまり強い方ではありません。エンタープライズでは今後も、.NETのようなサポートのあるプラットフォームも視野に入れるべきだと思っています。ケースバイケースですね。

このブログの筆者について

川田 寛

株式会社メディアドゥのVP of Engineering。ネットでは「ふろしき」と呼ばれている。

2009年、新卒としてNTTグループにて仮想化技術・Web標準の研究と技術コンサルティングに従事。2015年よりピクシブ株式会社にて、Webエンジニア・エンジニアリングマネージャー・事業責任者・執行役員などを通じて、技術組織のデザインと技術系の新規事業に関わる。2021年12月より、現職へとジョイン。

ネット事業と技術組織は表裏一体!良いネット事業は良い技術組織から!日本のコンテンツを一つでも多く世界へ届けるべく、技術組織デザインと新規事業の二足の草鞋を履いて邁進中。

このブログでは、主に「インターネット事業のビジネス基本知識」「Webテクノロジーのトレンド」「エンジニア組織の設計手法」について、経験談を交えつつ解説していきます。私と話をしてみたいという方は、以下のフォームより気軽にご連絡ください。

お問い合わせフォーム
免責事項: 本ブログの発言は個人の見解であり、所属組織を代表するものではありません。