読者です 読者をやめる 読者になる 読者になる

くろねこ日記

ソフトウェアに関する技術メモが多いです.

Electronはじめてみた

はじめに

ElectronというGitHubが公開しているデスクトップアプリケーション開発環境があります[1].

特徴としてはWebの知識だけでデスクトップアプリがつくれるところにあります.

今日はざっくりとElectronの導入から実行,パッケージングまでをラーメンタイマを例に上げて紹介します.

Electronとは

ElectronとはGitHubが公開しているデスクトップアプリケーションをNodejsをつかって開発することができる環境のことです.

ライセンスはMITで公開されており,商用にも問題なく利用ができます.

ネイティブなデスクトップアプリケーションを作るには,Windowsなら.Netに対応した言語(たとえばCSharpとか),OSXならCocoaに対応した言語(Swift),LinuxならGTKやQTなどがありますね.

これらに対応するにはそれぞれの言語を習得して使いこなさなければならず開発の手間も非常にかかってしまうという難しさがあります.ElectronはHTMLとJSの知識だけでOSX,Linux,Windowsに対応するネイティブなデスクトップアプリケーションを作ることができ,非常に便利なので今日はそのことについてまとめます.

環境構築

まずはElectron開発に必要な環境を整えましょう.

公式ページを見ても良いですが,qiitaの記事[2]がまとまっていたのでここを参照しつつラーメンタイマ開発環境を整えましょう.

shell

npm -g install electron-prebuilt

これでelectronをインストールします 次に開発するディレクトリを作りましょう

shell

mkdir /path/to/ramentimer

ramentimerというディレクトリ名にしました(笑).

shell

cd /path/to/ramentimer

ramentimerに移動して,

shell

npm init -y

対話シェルでいろいろ聞かれますが,無視してEnterを叩いていくとこれでpackage.jsonというファイルが生成されます.この中身を開くと

package.json

{
  "name": "ramentimer",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

となってます.mainで指定されているのがindex.jsなので,そこにelectronの基本的なコードを書いていくことになります.

ラーメンタイマの実装と実行

それではさっそく/path/to/ramentimerの中で作業をすすめていきましょう.

目標とするラーメンタイマは次のようなものです.見た目は図1と図2に示しました.

  • アプリを立ち上げたら3分カウントダウンして,3分経過したら「完成!」という文字列を表示する.

  • ウィジェット風にしたいので,アプリの背景は透過処理し,閉じるボタンなどは隠す.

f:id:kuroneko0208:20150921021644p:plain 図1: ラーメンタイマがカウントしている様子(中央の98sという文字列がアプリ)

f:id:kuroneko0208:20150921021921p:plain 図2: ラーメンタイマがカウントし終わった様子(「完成!」と表示している)

index.js(アプリの設定を書く)

まずはindex.jsというファイルをつくって次のようにElectronの基本的な設定を次のように書いていきましょう.

index.js

'use strict';

var app = require('app');
var BrowserWindow = require('browser-window');
require('crash-reporter').start();
var mainWindow = null;

app.on('window-all-closed', function(){
  if(process.platform != 'darwin'){
    app.quit();
  }
});
app.on('ready', function(){
  mainWindow = new BrowserWindow({width: 120, height: 80, transparent: true, frame: false});
  mainWindow.loadUrl('file://' + __dirname + '/index.html');
  mainWindow.on('closed', function(){
    mainWindow = null;
  });
});

最初のappやbrowser-windowはelectronが用意しているmodule(ただしい表現か怪しいです)です.

こちらにappやbrowser-windowに関する説明がのってます[3].

とりあえず,上記のコードで見てもらいたいのは

  mainWindow = new BrowserWindow({width: 120, height: 80, transparent: true, frame: false});
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

この2行です.

  mainWindow = new BrowserWindow({width: 120, height: 80, transparent: true, frame: false});

についてはアプリのウィンドウのサイズ(widthとheight)や透過処理(transparent)をOn,閉じるボタンや最小化・最大化ボタン(frame)を消す設定をしてます.

  mainWindow.loadUrl('file://' + __dirname + '/index.html');

こちらではElectronのViewにあたる部分を指定してます.

ここまではざっくりとElectronのチュートリアルにものってますし,[2]のリンクにものっているのでとりあえず書いておくものくらいで留めておきます.

index.html

index.htmlというファイルを実際のアプリの見た目に設定しましたので書いていきましょう.

ラーメンタイマのカウントダウンの値と「完成!」という文字を表示させる部分を含んだhtmlファイルをつぎのようにつくります.

index.html

<html>
  <head>
    <meta charset="UTF-8">
    <title>ラーメンタイマ</title>
    <style>
      body {
        -webkit-app-region: drag;
        -webkit-user-select: none;
      }
    </style>
  </head>
  <body>
    <h1><div id="output"></div></h1>
  </body>
  <script src="ramen.js"></script>
</html>

まずは,index.jsでは透過処理や閉じるボタンを排除したために,そのままだとドラッグや選択ができず不自由なので,そのための設定をcssで表現してます. なお,[4]に詳しい説明が載ってます. 次にカウントダウンの値と「完成!」を表示させるためのoutputというidをもつdiv要素を定義しました. その下ではramen.jsというファイルを読み込むようにしました.ramen.jsというファイルにindex.htmlを動的に変更(カウントダウンしたり)するような処理を書いていきます.

ramen.js

ではカウントダウンして表示するコードをramen.jsに書いていくと,

ramen.js

"use strict";

var i = 180; //3分固定
function count(){
  if(i <= 0){
    document.getElementById("output").innerHTML = "完成!";
  }else{
    document.getElementById("output").innerHTML = i + "s";
  }
  i -= 1;
}
window.onload = function(){
  setInterval("count()", 1000);
};

こんな感じです.htmlの読み込み(windowが立ち上がったら),setIntervalが動作して1sごとにcountという関数を実行させます. countという関数の中ではさきほどdivで定義したoutputというidにinnnerHTMLをつかって,表示してます.

これでとりあえず完成です.

シェルの中で shell

electron .

これでアプリが立ち上がるはずです

ここでは紹介しませんが,html5にはmp3を再生する機能があるので,カレントディレクトリにmp3ファイルを置いて,3分経過したら読み込ませて鳴らしたりすることもできます.Electronはこのあたりのファイルもちゃんと吸収してアプリを起動してくれるのですごいなと思いました.

ロスコンパイル方法

さて,Electronの目玉であるクロスコンパイルについて書いておきます.

ロスコンパイルするためには,次のようなツールをインストールしなければなりません

shell

npm install -g electron-packager

あとは次のコマンドでアプリをつくりましょう.ここではosx,linuxの2つのプラットフォーム向けにコンパイルしてみます.

shell

electron-packager ./ ramentimer --platform=darwin,linux --arch=x64 --version=0.30.0

ここについては[5]のリンクにくわしく書いてあるので読んでみると良いと思います.

このコマンドをたたくことで,それぞれの環境に応じたディレクトリができるので,中身を開いて動かしてみましょう.

まとめとさいごに

Electronをつかった簡易なラーメンタイマを例にしてelectronの開発手順をまとめてみた.

今回のアプリはsinatra sapporoのもくもく会の中でつくりました.sinatra sapporoに感謝!

参照

[1] Electron公式ページ http://electron.atom.io

[2] 30分で出来る、JavaScript (Electron) でデスクトップアプリを作って配布するまで - Qiita http://qiita.com/nyanchu/items/15d514d9b9f87e5c0a29

[3] Electron Documentation http://electron.atom.io/docs/v0.33.0/

[4] Frameless-windowの説明 http://electron.atom.io/docs/v0.33.0/api/frameless-window/

[5] パッケージングツールの説明 https://github.com/maxogden/electron-packager