Electron製アプリをChrome App化してみる

最近、人気のElectronですが、小さいアプリなんかはChrome Appで置き換えることで得られる利点もあるよ。という記事です。

Chrome Appについて

アプリケーションを作ったときに、Electronの場合は1アプリケーションにつき1つのChromium、Nodeが同梱されているような形になります。AtomやVSCodeのような規模の大きいアプリならそのような形式もいいと思うのですが、小さいアプリケーションならば1アプリごとに、ブラウザみたいなモジュールが組み込まれているのは無駄が多いと思われます。

electron-apps

Chrome AppはChromeの拡張機能みたいな作りになっていて、Chrome上で動く独立したタブのように機能します。Windowを表示することもできます。

chrome-apps

Electronアプリケーションと比べてみると、Electronはネイティブ操作が比較的自由にできますが、Chrome AppはChrome上で動作するために、サンドボックス下で動きます。その代わりChromeのAPIを通じた特殊な操作を権限を許可してもらってから利用できます。ちょうどスマートフォンアプリで「〜にアクセスしてもよろしいですか?」と権限の承認を求められる感じです。
それでも、Web上のJavaScriptとしてはアクセスできないような機能が使えるようになります。(USB, Bluetooth, 電源管理など)

Webアプリの場合は、タブを閉じてしまえばおしまいですが、Chrome Appはタスクトレイなどに常駐しつづけることもできます。

前回作ったElectron AppのChrome APp化

前回作ったものなのですが、特にネイティブAPIは使ってなくて、nodejsのメインプロセスからBrowserWindowを表示し、あとはブラウザの中の世界で表現されたアプリです。なのでChrome App化するのは簡単です。

Chrome Appは、manifest.jsonというファイルをアプリケーションの設定として使います。ここでbackgroundというElectronでいうメインプロセスのjsを指定します。

background.jsはタブやウィンドウを持たない状態で起動します。onLaunchedというイベントハンドラで処理を記述して、chrome.app.window.createでアプリケーションのWindowを起動します。Windowを作る処理はElectronのBrowserWindowと似ている感じです。Window起動時にhtmlを指定してブラウザを表示すれば、あとはブラウザと一緒です。

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('main.html', {
    id: 'MyWindowID',
    bounds: {
      width: 800,
      height: 600
    },
  });
});

ということで、Chrome App版も比較的カンタンに、作ることができました。

GitHub: civic/presen-timer

スクリーンショット 2015-11-23 17.28.34

ただ、Electronのときにやっていた透過ウィンドウはChrome Appでは対応していないようで透過することはできませんでした。

まとめ

ブラウザウィンドウを表示して、HTML+JavaScriptで実現するようなアプリケーションであればChrome Appでも実現できます。NDS45では簡単に作れるChrome Appについてお話をしようと思います。つづきはNDSで!


#ndsmeetup8 で聞いた内容を使ってアプリ作った

先日の NDS meetup8 「JavaScript Day」では色々なことを学んだわけですが、学んだ幾つかのトピックをつかって復習がてら「プレゼン用のタイマー」みたいなアプリを作ってみました。

よく訓練された聴講者みたいです!

GitHub: civic/presen-timer

アプリ自体は、大したことなくてただのストップウォッチです。プレゼン中にタイマー的に時間を表示するためのものです。

学んだ内容の復習として、以下の技術をピックアップして復習しました。

  • @circled9 さんの話から Mithril
  • @civic (私)の話からnpm、webpackだけでのビルド
  • @ushiboy さんの話から ES6
  • @yuw27b さんの話から Electronでアプリ化
  • @sakapun さんの話から Chroem Developer Toolでデバッグ

Mithrilでのコードは、プレゼンタイマーのストップウォッチ的機能と、それをコントロールするUIを分けて書いたんですがあんまりうまくかけてません。
わりとなんとでも書けてしまうのと、縛りがなさすぎてどう書くべきのかちょっと分からなくなってしまいました。。。たぶん自由なんだと思います。
ES6でクラス使えてるんですが、Controllerはクラスそのものを指定して、ViewModelなんかはインスタンス化したオブジェクトになってます。それでいいんだろうか。

WebPackでビルドするのは、無理にでもタスクランナーつかわなかったので、file-loaderつかってコピーしてます。

Electronでのアプリ化は、プロジェクト自体のpackage.jsonと、Electronにするためのpackage.jsonは同じでよいのか?ってことでちょっと迷いました。
透明ウィンドウでウィジェット的なものも作れるってことだったので、透明ウィンドウにしてみました。

こんな感じで透過ウィンドウのタイマーみたいな感じです。
Cursor_と_PresenTimer-darwin-x64_と_PresenTimer-darwin-x64

「これで、ミラーリング表示したプレゼンで、タイマーを表示しておくことができるぞー」って思ったのですが、、

1

アッ、アッ・・・
3

5

https://gyazo.com/692c682db806073eb330864bcf78165a

プレゼンテーション開始すると、プレゼンが全画面表示になるのでアプリが見えなくなるんですねー。

ということで、本来の目的では使えないアプリとなってしまいました。

まっ、でも勉強になりました。Electronは簡単マルチプラットフォームなアプリ作成に便利なので、今後も使っていきたいです。あとでChrome App版も作ってみようっと。


NDS in Niigata 8 JavaScript Day で発表してきた #ndsmeetup8

11/14に行われた第8回 NDS in Niigataに参加して発表してきました。

長岡版のNDSよりも集まりが良くて、「なんだよー新潟市のポテンシャル!悔しい!」ってなったんですが、これもdictavさんの人柄でしょう!新潟を去っても時々遊びに来てください!ありがとうございました!

自分の発表について

私の発表としては、「むずかしくないJavaScriptのやさしい話」というタイトルで初心者向けの内容で発表してきました。当初告知ページを見たときにはReactとかのネタが多かったのです。「これではWebデザイン界隈からJavaScriptの話を聞きに来た人がついていけないのでは?」と思ったので内容を決めず方針だけ「初心者向けの話をします」とだけ決めて申し込みました。

内容は色々迷ったのですが、jQueryとか使ってscriptタグ挿入してリロードしながら開発してするようなスタイルから、npmとかWebPackでビルドしてみようってところまで紹介しました。

発表中にデモしたことを振り返りできるようにチュートリアル用意しましたので、同じことを体験する場合にどうぞ。
JavaScript – npmとwebpackでビルド – jQueryからの次のステップ – Qiita

もっとデモに時間かけていろいろやるつもりだったのですが20minに収まらなくてなにかと削りました。ごっそり削ったんですが「jqueryをダウンロードしてscriptタグを挿入する」ってフローだけはどうしても削りたくありませんでした。そこがいちばん馴染み深いところだろうなと思ったからです。

結果として、私の発表内容の感想で「チェック2,3個の自分だったので分かりやすかったです」といった意見をいくつか頂けました。紹介した知識を持ち帰ってもらえたなーって感じられました。

他の人の発表について

circled9さんの、Frontend Fantasyが面白かったのと、覚えることが少ないっていう点が興味深かったです。
「ビルドに消耗しているの?」っていう意見は同感で、いろんなツールまで組み合わせたうえでのビルドは覚えることが多くて大変なので、「WebPackのCLIだけでも結構いいじゃん」って思っての私の発表でした。

sakapunさんのChrome Developer Toolの小技については知らなかったことが多かったです。Dev Toolはほんといろんな機能あって面白いですね。blackboxとか globalにコピーする奴とか知りませんでした。sakapunさんの業務の話は全然知らない未知の世界のことが聞けてホント興味深いです。懇親会でもいろいろと聞けて楽しかったです。

yuw27bさんのはElectronの紹介のLTでした。発表では紹介だけでしたが懇親会でたくさん突っ込んだ話を質問できました。常駐はわからないとのことでしたが、透明ウィンドウとウィンドウの枠・バーを消すことはできるから、ウィジェット的なのも作れるってことだったので、「そのへんの機能までマルチプラットフォームで作れるの楽しそう」と感じました。振り返りでなにか作ってみたい気もします。

あと個人的な主張として、Electronで自分がアプリを作る側として非常に便利だと思うんですが、Electron製アプリを使う側として「いまMacで使われているようなアプリが全部Electron製になる未来は嫌だ」って思ってます。エディタだのファイラーだのプレイヤーだの、いろんなアプリが起動している状態でそれらが全部がChromeみたいな重いプロセスだったらヤじゃないですか。ブラウザ部分は共通とかになってくれたほうがいいなって思います。
そこで、Chrome Appを推してみました。Chrome AppはElectronほど自由にはできませんが、ブラウザでアプリをってのをChromeの上で動かしていて、API経由でしかネイティブ操作はできませんが、USBやbluetoothも触れるのでもっと流行るといいなぁって思いました。コントローラー使ったゲームをChrome Appでとか出てほしいなと思います。

ushiboyさんは、会社の同僚です!ES6についての弾丸ツアーということでLTらしいテンポの良い発表でした。LT5分なのに50枚以上のスライドなのでいかに高速だったか。。。
ES6 モダンシンタックス弾丸ツアー

sugagggさんのJSゲームの話では、「Webゲームはいろんな制約があるけどTwitterなんかでリンク貼るだけですぐにフィードバック得られる」って言ってたのが目からウロコで、ゲーム作れないけどそういう感覚味わってみたいって思いました。

感想書いたのが、LTばっかりでスミマセン。。

その他

別に今回の発表で見受けられた意見ってわけじゃないんですが。

「お察しください」って最近良く言われるんですが、「えっ?どういうこと?聞いちゃいけないの?」って理解できないことがあるんですよ。
明らかに自明な場合に使うならいいと思うんですが、なんでも最後に説明を省いて「〜の件については…お察しください」って言うのはあまり良くないと思います。なにかダメなんだろうなってのは伝わるんですが、質問もしづらいし、どういうことなのか闇に葬られたままになってしまうので。

「Xではこのように使えるのですが、じゃあYの場合はどうかというと…お察しください」
わかっている人はクスクス(苦笑)
わかってない人はポカーン。。(聞いちゃいけないのかな…)

って感じで、必要な人にメッセージがほとんど届かないじゃないですか。言いにくい内容かもしれませんが、ちゃんと言葉をチョイスして「Yの場合は、〜という問題もあってあまり良くないんですよね」って言葉にしたほうが、わからなかった人にもメッセージが伝わると思います。そういう内輪ウケみたいなのは発表者は手間を省いて楽かもしれませんが、聞いてる方はなにも得しないので。

第45回NDSは12/5です。懇親会は、新潟 Developers 忘年会 NDB2015となります。よろしくお願いします!
第45回勉強会 (2015/12/05) – 長岡 IT開発者 勉強会(NDS)