ElectronにMilkcocoaを導入して、リアルタイムなデスクトップアプリを作る方法

Posted: / Tags: Electron



Electronは、デスクトップアプリケーションをJavaScriptで作成できてしまうGithub社が開発しているツールです。(Atom(原子)の次はElectron(電子)、なんだかかっこいいですね)

Atomはもちろん、Slackや、先日無料化されたPixateといった有名アプリにも使われているとのことで、安心して使えそうです。

そこで今回は、Electronで作ったアプリにMilkcocoaを導入する方法を簡単に説明します。

実際に作ったアプリのダウンロードリンクは以下になります。

Electronをインストールする

Electronをグローバルにインストールします(Node.jsは既にインストール済みであるとします)。

$ npm -g install electron-prebuilt

プロジェクトを作成します。

$ mkdir electron-milkcocoa && cd $_
$ npm init -y

npm initを実行すると、package.jsonが生成されます。

Electronは、package.jsonmainに書かれているファイルを、プログラムの開始地点として実行するようになっています。

公式がmain.jsにしているので、デフォルトがmain.jsではないものであればmain.jsに変更します。

package.json
{
  ...
  "main": "main.js",
  ...
}

アプリの枠組みのJavaScriptを書く

ElectronのQuick Start Guideをコピペして、アプリの枠組みとなるファイル(main.js)を作成します。

main.js
'use strict';

var app = require('app');
var BrowserWindow = require('browser-window');

require('crash-reporter').start();

// mainWindowはグローバルにしとかないとGCで勝手に閉じてしまう
var mainWindow = null;

// ウインドウが全部閉じたら実行
app.on('window-all-closed', function() {
  // Macとか(darwin)では、Cmd + Q が押されない限りアプリは終了させない
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// Electronの初期化完了後に実行
app.on('ready', function() {
  // メインウインドウ
  mainWindow = new BrowserWindow({width: 800, height: 600});
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  // メインウィンドウが閉じられたら実行
  mainWindow.on('closed', function() {
    // 参照外し
    mainWindow = null;
  });
});

コピペで大丈夫です。mainWindow.loadUrl('file://' + __dirname + '/index.html');と書いているように、index.htmlにアプリの中身を記述していきます。

アプリの中身となるHTMLを書いていく

アプリの中身となるindex.htmlを作成して、HTMLを書いていきます。

今回は、Milkcocoaのサンプルにあるチャットを作ってみましょう。

Electron用にHTMLをいじる必要は無く、基本的にサンプルチャットのソースコードをコピペするだけで大丈夫です。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Milkcocoa Chat with Electron</title>
  <link rel="stylesheet" href="style.css" type="text/css" />
  <script src="index.js"></script>
</head>

<body>
  <div class="header">
    <h1 class="logo">Milkcocoa Chat with Electron</h1>
  </div>
  <div class="container">
    <div class="postarea cf">
      <div class="postarea-text">
        <textarea name="" id="content" cols="30" rows="10" placeholder="Enterで投稿"></textarea>
      </div>
      <div class="postarea-share cf">
      </div>
      <button id="post" class="postarea-button">投稿する</button>
    </div>
  </div>
    <div id="messages" class="content">
      <div id="dummy"></div>
    </div>
    <p class="footer"><strong>Powered by <a href="http://mlkcca.com/">Milkcocoa</a></strong></p>
</body>
</html>

CSSファイルもコピペして同フォルダ内にstyle.cssとして保存してください。

サンプルチャットのソースコード内で直書きしているスクリプトは、わかりやすいようにJSファイル(index.js)にしました(jQuery、Milkcocoaもindex.js内で読み込みます)。

チャット部分のJavaScriptを書く(ElectronでMilkcocoaを使う)

HTMLが書けたら、チャット部分のスクリプト(index.js)を書いていきます。

これも一部を除き、サンプルチャットのソースコードをコピペで大丈夫です。

忘れずにmilkcocoaもインストールしておきます。

$ npm i milkcocoa

※Milkcocoaに登録していない方は、Milkcocoaで登録をしてアプリを作成し、アプリの管理画面のapp_idを控えておいてください。

index.js
'use strict';

var remote = require('remote');
var MilkCocoa = remote.require('milkcocoa');
var $ = require('./lib/jquery.min.js');

// 1.ミルクココアインスタンスを作成
// app_idの部分は、Milkcocoaに(無料)登録してアプリを作成した際に生成されるアプリ固有の文字列です。
var milkcocoa = new MilkCocoa("app_id.mlkcca.com");

// 2."message"データストアを作成
var ds = milkcocoa.dataStore("message");

$(function() {
  // 3."message"データストアからメッセージを取ってくる
  ds.stream().size(30).sort("desc").next(function(err, data) {
    // Electronでコンソールを見たいときは
    // main.jsのapp.on('ready')の中で
    // mainWindow.openDevTools(); と書くとDevtoolsが現れます。
    if(err) console.log(err);
    data.forEach(function(d) {
      renderMessage(d);
    });
  });

  // 4."message"データストアのプッシュイベントを監視
  ds.on("push", function(pushed) {
    renderMessage(pushed);
  });

  var last_message = "dummy";

  function renderMessage(message) {
    var message_html = '<p class="post-text">' + escapeHTML(message.value.content) + '</p>';
    var date_html = '';
    if(message.value.date) {
      date_html = '<p class="post-date">'+escapeHTML( new Date(message.value.date).toLocaleString())+'</p>';
    }
    $("#"+last_message).before('<div id="'+message.id+'" class="post">'+message_html + date_html +'</div>');
    last_message = message.id;
  }

  function post() {
    // 5."message"データストアにメッセージをプッシュする
    var content = $("#content").val();
    if (content && content !== "") {
      ds.push({
        content: content,
        date: new Date().getTime()
      });
    }
    $("#content").val("");
  }

  $('#post').click(function () {
    post();
  });

  $('#content').keydown(function (e) {
    if (e.which == 13){
      post();
      return false;
    }
  });
});

//インジェクション対策
function escapeHTML(val) {
  return $('<div>').text(val).html();
};

ポイントは以下です。

remoteを使ってMilkcocoaを読み込む

Milkcocoaを読み込む場合、remoteオブジェクトを使って読み込む必要があります。直接requireすると、レンダリング処理の中で実行されてしまうからです。

remoteについては以下の記事を参考にして下さい。

remoteはElectronにデフォルトで入っているのでインストールはしなくていいです。

jQueryをrequireで読み込む

こちらの記事によると、jQueryを普通にHTML内で読み込むと使えないとのことなので、プロジェクト内にjquery.min.jsを置いてrequireで読み込みましょう。

実行してみる

完成したので、実行してみましょう。プロジェクトの一番上のディレクトリ(今回は/electron-milkcocoa/)で以下のコマンドを実行します。

$ electron .

成功すれば、Milkcocoaのサンプルチャットと同じ見た目のアプリが起動するかと思います。

うまく動かないときは、main.jsmainWindow.openDevTools();と書いて実行して、DevToolsでデバッグしましょう。

main.js
app.on('ready', function() {
  ...
  mainWindow.openDevTools();
  ...
});

Electronを簡単にリアルタイムに

今回は、ElectronのアプリにMilkcocoaを導入する方法を説明しました。

Electronは既存のHTMLやJavaScriptをほぼコピペで動かすことが出来るのがわかったかと思います。 この簡単さに加え、Milkcocoaを使うことで、あっという間にリアルタイムアプリを作ることができます。

ブラウザ上のアプリとデスクトップアプリで同じデータストアを使えば、同期も簡単に出来ますね。

アプリケーションとして配布したい場合は以下の記事を参考にしてください(今回の記事作成でも大変参考にさせて頂きました!)

こちらの記事を参考にアプリケーション化したもののリンクを、もう一度貼ります。

皆さんもどんどんアプリを作成して配布して頂けると幸いです。