clojureでelectronアプリを作ろう

39
Clojureで Electronアプリつくろう {:company “Greative GK” :name “Kazuhiro Hara” :twitter “kara_d” :github “https://github.com/karad ”} Electron(旧:Atom-Shell)勉強会 #1

Upload: kazuhiro-hara

Post on 18-Jul-2015

1.219 views

Category:

Internet


2 download

TRANSCRIPT

ClojureでElectronアプリつくろう

{:company “Greative GK” :name “Kazuhiro Hara” :twitter “kara_d” :github “https://github.com/karad”}

Electron(旧:Atom-Shell)勉強会 #1

#atom_shelldescjop.org

自己紹介

2

原 一浩ハラ カズヒロ

ClojureScript + Electronのプロジェクトテンプレdescjopの作者

http://greative.jp/

( @kara_d )

http://descjop.org/

#atom_shelldescjop.org

ちょっと前の著書➡ Play Framework 2徹底入門 - JavaではじめるアジャイルWeb開発

3

実践編(4章~7章)を担当

✦サンプルアプリの企画から設計、構築、テスト、管理画面作成までを一通り

マニュアルにはない詰まりポイントとかもちりばめられてます。

#atom_shelldescjop.org

アジェンダ➡ Clojureについて➡ ビルドツールについて➡ ClojureでElectronアプリをつくるには➡ demo➡ Clojureならでは話➡ ClojureScript & Node.jsハマりどころ➡ 今後の課題

4

#atom_shelldescjop.org 5

そもそもClojureってなに話

#atom_shelldescjop.org

Clojureってなに? ➡ Lisp方言

S式

データとしてのコード成長可能な言語

➡ 関数型プログラミング第一級関数イミュータブルなデータ構造

6

(println  (+  1  2  3))  ;  =>  6

#atom_shelldescjop.org

Clojureってなに? ➡ 豊かなビルド環境

LeiningenREPLClojarsJavaのライブラリ or Nodeのライブラリ

➡ 複数のビルドターゲットJava環境JavaScript環境.NET環境

7

#atom_shelldescjop.org

Clojureあれこれ ➡ Clojureは新しいけど、すごく古くもある

Clojureが生まれたのは、2007年LISPは、2番目に古い高級言語

➡ ClojureScriptはJavaScript向けコンパイル環境JavaとJavaScriptの関係とは、ちがう同一シンタックスで書ける拡張子は、Clojureが.clj、ClojureScriptが.cljs

➡ ClojureScriptは、AltJSとしては、そこそこ古いJun 3, 2011に最初のコミット

8

#atom_shelldescjop.org

LightTableはClojureScript製➡ かなりの実用度!!

9

#atom_shelldescjop.org

Clojureは読みやすい(他のLispよりちょっとだけ)

➡ JavaScript

➡ Clojure

10

function  hoge  (param)  {      console.log(“Hello  world!”);}

(defn  hoge  [param]      (println  “Hello  world!”))

#atom_shelldescjop.org

Clojureを選んで何がいいのか➡ フロントエンドのJavaScript、バックエンドのJVMベースサーバを強力な言語機能で統一的に作り上げることができる

11

Clojure

WebJVMServer Electron

APIAPI

#atom_shelldescjop.org 12

ビルドツールについて

#atom_shelldescjop.org

ビルドツールについて➡ ClojureとClojureScriptのビルドツール、LeiningenNode、Npm、Grunt/Gulp/Bowerやテストランナーがくっついたようなもの

13

$  lein  new  アプリ名

$  lein  cljsbuild

$  lein  test

#atom_shelldescjop.org

ClojureScriptのコンパイル➡ project.clj

ビルド情報を書くpackage.jsonみたいなもの

➡ lein-cljsbuildを使うleinコマンドからClojureScriptのコンパイルができる

➡ ClojureScriptのコンパイルGoogle Clojure関係がライブラリとして使われていたり、コンパイラとして使われたりしている

14

$  lein  cljsbuild  once

#atom_shelldescjop.org

JavaScriptにコンパイルされた時のサイズ➡ :optimizations :simple

400KB~2MBくらいになっちゃうこれは重い

➡ :optimizations :advanced数十から百KB程度これならなんとか

15

#atom_shelldescjop.org 16

ClojureでElectronアプリをつくるには

#atom_shelldescjop.org

Electronアプリ用のLeiningenツール

➡ http://descjop.org➡ リリース後の顛末

公開したのが4/17その日にAtom-Shell -> Electronリポジトリも変更Gruntタスク周りで本家にissue作成無事パッチが当てられ、再リリース

17

#atom_shelldescjop.org

ClojureでElectronアプリをつくるには➡ descjop.orgを使って開始すると楽

➡ 使ってみて良い感じだったら★ください~

18

$  lein  new  descjop  アプリ名

#atom_shelldescjop.org

何が生成されるのか?

19

├──  README.md├──  app│      ├──  index.html  //  トップページ│      ├──  js│      │      └──  main.js│      └──  package.json  //  アプリ用package.json

├──  package.json  //  コンパイル用package.json

├──  project.clj  //  Clojureのコンパイル設定└──  src        └──  NAMESPACE                └──  core.cljs  //  ClojureScriptを置く

#atom_shelldescjop.org

descjopのしくみ : その1➡ lein cljsbuildをすると、src/###/core.cljsがapp/js/cljsbuild_main.jsとしてコンパイルされる

/src/###/core.cljs

↓ コンパイル

/app/js/cljsbuild_main.js

20

#atom_shelldescjop.org

descjopのしくみ : その2➡ cljsbuild_main.jsは、app/js/main.jsから呼ばれる

/app/js/cljsbuild_main.js

↑ 呼ぶ

/app/js/main.js

21

#atom_shelldescjop.org

descjopのしくみ : その3➡ Electronは、app以下のpackage.jsonを通じてmain.jsを呼び出す

/app/js/cljsbuild_main.js

↑ 呼ぶ

/app/js/main.js

↑ 呼ぶ

/app/package.json22

#atom_shelldescjop.org

descjopのしくみ : その4➡ cljsbuild_main.jsからは、BrowserWindowとして、index.htmlをloadUrlする

/app/index.html

↑ ロードする

/app/js/cljsbuild_main.js

23

#atom_shelldescjop.org

Electron、ClojureとClojureScriptの関係

24

Clojure界

ClojureScript界

JavaScript界

Electron界

COMPILE

マクロなど

.clj.cljs.jsAPI

Leiningenによる

#atom_shelldescjop.org 25

demo

#atom_shelldescjop.org

demo

26

$  npm  install  -­‐g  grunt-­‐cli

$  npm  install

$  grunt  download-­‐electron

$  lein  externs  >  app/js/externs.js

$  ./electron/Electron.app/Contents/MacOS/Electron  app 5

4

3

2

1

$  lein  new  descjop  アプリ名

#atom_shelldescjop.org

ビルド終了後の構成

27

├──  README.md├──  app│      ├──  index.html  //  トップページ│      ├──  js│      │      ├──  cljsbuild-­‐main.js  //  コンパイル済JS

│      │      ├──  externs.js│      │      └──  main.js│      └──  package.json  //  アプリ用package.json

├──  package.json  //  コンパイル用package.json

├──  project.clj  //  Clojureのコンパイル設定└──  src        └──  NAMESPACE                └──  core.cljs  //  ClojureScriptを置く

#atom_shelldescjop.org 28

Clojureならでは話

#atom_shelldescjop.org

こんな構文あったらいいな➡ appに対して、イベントハンドラ設定めんどい➡ こんな構文が欲しいとする

29

(var的なもの  app名  app生成                      :イベントハンドラ  (関数)

                     :ほかのハンドラ  (関数)

                     ...  ...)

#atom_shelldescjop.org

ちょいとマクロ➡ マクロは、ClojureScriptではなく、Clojureとして書く

➡ ただし、関数でできる場合は関数で書こう

30

(defmacro  defatomshellapp    [name  app  &  clauses]    `(loop  [cl#  [~@clauses]]          (if  (and  (not  (nil?  cl#))  (first  cl#)  (next  cl#))              (do                  (.on  ~app  (name  (first  cl#))  (second  cl#))                  (recur  (next  (next  cl#))))              (defonce  ~name  ~app))))

#atom_shelldescjop.org

こんな風に呼び出せる➡ 欲しかった構文を拡張できる

31

(defatomshellapp  app  (nodejs/require  "app")    :ready  (fn  []  (  処理  ))

   :window-­‐all-­‐closed  (fn  []  (  処理  ))))

#atom_shelldescjop.org 32

ClojureScript & Node.jsハマりどころ

#atom_shelldescjop.org

注意ポイント➡ externs

advancedオプションにてサイズを小さくするときに、必要な変数名などの書き換えをさせないための指定js/externs.jsとかに記述するlein-externsを使うと楽

33

$  lein  externs  >  app/js/externs.js

#atom_shelldescjop.org

注意ポイント➡ externs

js/externs.jsは、こんな風になる

34

var  TopLevel  =  {"BrowserWindow"  :  function  ()  {},"console"  :  function  ()  {},"loadUrl"  :  function  ()  {},"log"  :  function  ()  {},"on"  :  function  ()  {},...}

#atom_shelldescjop.org

注意ポイント➡ nodeモジュール関係

node関係のモジュールもexternsすることpackage.jsonに

project.cljに

35

:externs  ["app/js/externs.js""node_modules/closurecompiler-­‐externs/path.js""node_modules/closurecompiler-­‐externs/process.js"]

"closurecompiler-­‐externs":  "^1.0.4"

#atom_shelldescjop.org

注意ポイント➡ pathまわり

開発時と、ネイティブアプリケーションとしてパッケージングした時の取得可能なパスがメソッドによって異なるので注意

36

(str      "file://"    (.resolve  path  (js*  "__dirname")    "../index.html"))

#atom_shelldescjop.org

注意ポイント➡ その他

よくJavaScriptの関数を渡す場面で、へんなものが渡るときがある。きちんと無名関数を渡そうオブジェクトは、clj->jsを使って渡す

37

(clj-­‐>js  {:width  800  :height  600})

#atom_shelldescjop.org

今後の課題➡ NW.js用のスカフォルディングの提供➡ gruntタスクからgulpへの移行➡ UI周りで構成をいろいろ考え中➡ 今は遊びがてら学習サイクルまわし中

38

学ぶ

作る問う

ありがとうございました!!

Electron(旧:Atom-Shell)勉強会 #1

ClojureでElectronアプリつくろう

{:company “Greative GK” :name “Kazuhiro Hara” :twitter “kara_d” :github “https://github.com/karad”}