{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 業務アプリケーションをElectronで作ってみた\n", "\n", "[合同勉強会 in 大都会岡山 -2015 Winter-](https://gbdaitokai.doorkeeper.jp/events/31149)\n", "\n", "[忘年会議2015](https://bonenkaigi.doorkeeper.jp/events/27273)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## おまえ、誰よ\n", "\n", "**よしだ**\n", "\n", "* twitter: [@grimrose](https://twitter.com/grimrose) /とーます\n", "\n", "* Community: [Yokohama.groovy](http://connpass.com/series/253/)\n", "\n", "* 好きな言語: [Groovy](http://www.groovy-lang.org)\n", "\n", "* 好きなIDE: ![IntelliJ IDEA](https://www.jetbrains.com/idea/docs/logo_intellij_idea.png)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## お仕事\n", "\n", "所属: とある人材紹介会社のマーケティング部門\n", "\n", "役割: データ分析チームのデータエンジニア\n", "\n", "* 社内BIツールの開発、設計、運用\n", " * ScalikeJDBC + Scalaz + Hazelcast、FuelPHP、Angular + TypeScript、etc...\n", "* 業務改善(BPR)チームの技術担当 **<- 今回はこっち**\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## BPR\n", "\n", " **Business Process Reenginnering **\n", " \n", " / びじねすぷろせすりえんじにありんぐ\n", " " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## みんな大好き、Excel" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 要望\n", "\n", "**とある業務を将来的に自動化したい**\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 課題\n", "\n", "* データがあちこちに散らばっていている\n", "* Excel、Accessだったり…\n", "* 職人によるぬくもりのある手作業によるmerge\n", "* 本当はもっと多くのデータと結合させたい\n", "* これまでのデータも活用したい\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## やっぱり、Webで!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## いきなりは難しい…\n", "\n", "* いろいろやろうとするとかなりの規模に\n", "* 社内BIのAPIを使えるとそのデータも活用できるかも?\n", "* データの中には、機微情報も含まれる可能性が…\n", "* とはいえ、諸問題が解決したら将来的には社内BIに取り入れたい\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## じゃあ、GUIで?\n", "\n", "AccessやExcelならVBA?\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## またまた、ご冗談を(AA略" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "🙅 **VBAで立ち止まっている暇は無い**" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 調査と検証(と称したトライアル)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 候補\n", "\n", "* [JavaFX](http://www.oracle.com/technetwork/jp/java/javafx/overview/index.html)\n", "* [py2exe](http://www.py2exe.org)\n", "* [Electron](http://electron.atom.io)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## JavaFX\n", "\n", "😆\n", "\n", "* 慣れ親しんだJava\n", "* ライブラリ豊富\n", "* IntelliJ IDEAとScene Builder\n", "* LinuxでビルドしてそのままWindowsで(大抵)使える\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## JavaFX\n", "\n", "😞\n", "\n", "* exe形式にするにはWindowsでビルドする必要あり、しかもかなりサイズがデカい\n", "* 逆にスタンドアローンだと**利用者に**社内スタンプラリーを強いる\n", "* Java8からJDBC-ODBC ブリッジドライバが含まれなくなった\n", "* JavaFX書いたことあるのは、チームで自分だけ" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## py2exe\n", "\n", "😆\n", "\n", "* IntelliJ IDEAで作れる\n", "* ライブラリ豊富\n", "\n", "😞\n", "\n", "* Windowsでビルドする必要あり\n", "* Windowsにpythonをインストールするための社内スタンプラリー\n", "* チーム全員Python入門者\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Electron\n", "\n", "😆\n", "\n", "* IntelliJ IDEAで(ry\n", "* 中身はWebアプリ\n", "* node.jsのライブラリが使える\n", "* 時代を先取る、ニュー(ry\n", "* node.jsをインストールしなくてもwindowsで動く\n", "* JavaScriptならチーム全員使える\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Electron\n", "\n", "😞\n", "\n", "* [gulp](http://gulpjs.com)初心者\n", "* [Babel](https://babeljs.io)初心者\n", "* そもそも[Node.js](https://nodejs.org/en/)で本格的に開発するのは初めて\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 続きは忘年会議で!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# 業務アプリケーションをElectronで作ってみた -後半戦-\n", "\n", "[忘年会議2015](https://bonenkaigi.doorkeeper.jp/events/27273)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## おまえ、誰\n", "\n", "**よしだ**\n", "\n", "所属: とある人材紹介会社のマーケティング部門\n", "\n", "役割: データ分析チームのデータエンジニア\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Electronならワンチャンある?\n", "\n", "いきなりは難しいので、個人で始めてみる" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 希望\n", "\n", "* ElectronだとほぼSPAらしいので、SPA向けのフレームワークを使いたい\n", "* jQueryの無い世界へ\n", "* モダンなビルド環境\n", "* 初めてなのでベースとなるボイラープレートが欲しい" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## ボイラープレート\n", "\n", "[React + Babel + Sass + Gulp + Bower な Electron Boilerplate](http://qiita.com/superbrothers/items/6ded4e37ac021030982a)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## [React.js](https://facebook.github.io/react/)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "( ゚д゚)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 挫折" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 他に無いかなぁ…" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "[Electron + Mithrilで、ふつうのデスクトップアプリを作る](http://qiita.com/shibukawa/items/e1836a8c98413448f746)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.js\n", "\n", "http://mithril.js.org \n", "\n", "[Mithrilのドキュメントの日本語訳](http://mithril-ja.js.org/index.html)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.js\n", "\n", "[世界最速でMithril本をリリースした話](http://blog.shibu.jp/article/160479412.html)\n", "\n", "[Mithril――最速クライアントサイドMVC](http://www.oreilly.co.jp/books/9784873117447/) (通称黒ムツ本)\n", "\n", "[oreilly-japan/mithril-book-sample](https://github.com/oreilly-japan/mithril-book-sample)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 覚えることが少ない、しかも早い\n", "\n", "速さこそ正義" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## これだ!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## その他のライブラリ\n", "\n", "* [Babel.js](https://babeljs.io) - トランスパイラ\n", "* [Loki.js](http://lokijs.org/) - Mongo LikeなAPIを持つストレージエンジン\n", "* [mgcrea/node-xlsx](https://github.com/mgcrea/node-xlsx) - xlsxファイルの読み書きとJSON化\n", "* [Pure](http://purecss.io) - 軽量CSSフレームワーク\n", "* [font-awesome](https://fortawesome.github.io/Font-Awesome/) - Webフォントアイコン\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## あとで分かったこと\n", "\n", "採用しようとしたが断念したライブラリ\n", "\n", "* [sqlite3](https://www.sqlite.org/cli.html)\n", "* [LevelDB](http://leveldb.org)\n", "\n", "windowsでビルドする必要あり 😭\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.jsを知る\n", "\n", "まずは、[Getting Started](http://mithril.js.org/getting-started.html)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.jsをもっと知る\n", "\n", "* [Welcome to the Mithril wiki!](https://github.com/lhorie/mithril.js/wiki)\n", "* [Learn Mithril](http://lhorie.github.io/mithril-blog/)\n", "* [Mithril.js: A Tutorial Introduction (Part 1)](http://gilbert.ghost.io/mithril-js-tutorial-1/)\n", "* [Mithril.js: A Tutorial Introduction (Part 2)](http://gilbert.ghost.io/mithril-js-tutorial-2/)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.jsをもっと知る\n", "\n", "[Dave's guide to Mithril.js Part 1](http://ratfactor.com/daves-guide-to-mithril-js?/shire)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.jsをもっと知る\n", "\n", "[Qiita](http://qiita.com/tags/Mithril.js)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.jsを使ってみた\n", "\n", "**Component**\n", "\n", "* それぞれのComponentを疎にしておくと再利用しやすい(アラートボックス等)\n", "* 親 -> 子の一方向だと分かりやすい\n", "* 双方向に通知させようとすると結構大変" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.jsを使ってみた\n", "\n", "**ラウター**\n", "\n", "* 基本は、**m.mount**\n", "* ComponentとURLを関連付けるなら、**m.route**\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Mithril.jsを使ってみた\n", "\n", "**View**\n", "\n", "* JSXのようなMSXを使わなくても、`m()`だけでも結構行ける\n", "* [自動再描画システム](http://mithril-ja.js.org/auto-redrawing.html)\n", " * **m.redraw()**\n", " * **m.startComputation / m.endComputation**\n", "* ヘルパーメソッドの置き場所を考えておく\n", " * ViewModel\n", " * Controller" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 今後\n", "\n", "**React.js**\n", "\n", "* リベンジしたい\n", "* まずは、[Tutorial](https://facebook.github.io/react/docs/tutorial.html)をやり切る\n", "* 次は、[Browserify](http://browserify.org)と組み合わせてもう一回やる\n", "* [Redux](https://github.com/rackt/redux)と併せて作ってみる\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 今後\n", "\n", "**テストコード**\n", "\n", "* プロトタイプなのでまだ無い(アカン\n", "* Electronのテストの書き方を知る\n", "\n", "**継続的デリバリー**\n", "\n", "* ElectronのCIの回し方を知る\n", "* 社内の閉じた環境でも[autoUpdater](https://github.com/atom/electron/blob/master/docs/api/auto-updater.md)が使えるか試してみる\n", "* versionアップに着いて行く\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## まとめ\n", "\n", "

electronで業務アプリ書くのはある程度悪くない解決手段かもしれない。 IE8に縛られて疲弊するよりelectronの進化に付いていく方がまだ経験値が得られると思う。

— とーます (@grimrose) 2015, 10月 20
\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## 最後に\n", "\n", "* 片手間でフロントエンドをやるのは、正直シンドい\n", "* JavaFXを選択できた世界線も見てみたい\n", "* 素朴なVBAで疲弊するより、未来に向けて進化するECMAScript\n" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Scala 2.11", "language": "scala211", "name": "scala211" }, "language_info": { "codemirror_mode": "text/x-scala", "file_extension": "scala", "mimetype": "text/x-scala", "name": "scala211", "pygments_lexer": "scala", "version": "2.11.6" } }, "nbformat": 4, "nbformat_minor": 0 }