shadow-cljs使ってなんか作るRTAはっじまるよー
現在15日の金曜夜、計測スタート
スケルトンプロジェクトを作成
shadow-cljsは一から使った事ないのでさっとググって読んでみる
これ良さそうだな
最初のスケルトンプロジェクトはこれでいこう
なりお世話になったが、 shadow-cljs と reagent 入れた所でおわりか
reagentのアップグレード
ついでに GitHubのreagent を見ながら 1.2.0
の最新にしたらclojure-lspにより怒られが発生
そういや reagent.dom
を使ってくださいみたいなのあった気がする。
Examplesを見るとこのような感じで紹介されている事を確認
(ns example
(:require [reagent.core :as r]
[reagent.dom :as rd]))
(defn mountit []
(rd/render [childcaller]
(.-body js/document)))
r/render
をrd/render
に変更するだけだな。
よし通ったし画面も表示される。
Reactを17系にダウングレード
確かに画面は表示されるが、
デベロッパーツールを開くと「この書き方は18系としては古いので新しい書き方に変更してください」とか怒られる
reagentのREADME.mdを確認すると、18系は動かしてなさそう
or by adding Cljsjs React packages to your project:
[cljsjs/react "17.0.2-0"] [cljsjs/react-dom "17.0.2-0"]
Note: Reagent is tested against React 17, but should be compatible with other versions.
17系までしかテストしてません!そんなことある?
Issueを軽く覗いたら「React 18に早く対応してくれ!」みたいなのが複数あったからそのうち対応されそう。
- tasks
- GitHubでリポジトリを作る
- shadow-cljsのプロジェクトを作る
- reagentを入れる
- ルーターを入れる
- re-frameを入れる
- 自宅サーバーに向けてAjaxを飛ばしてJSONを受け取る
- Webアプリをガリガリ書く
ルーターを入れる
複数画面でページ遷移出来るものが作りたい
少し調べたら react-router-dom
の機能を使って上手く書くサンプルが出てきた
(defn root []
[:> Router
[:div
[:nav
[:ul
[:li
[:> Link {:to "/"} "Home"]]
[:li
[:> Link {:to "/about/"} "About"]]
[:li
[:> Link {:to "/users/"} "Users"]]]]
[:> Route {:path "/" :exact true :component Index}]
[:> Route {:path "/about/" :component About}]
[:> Route {:path "/users/" :component Users}]
]])
シンプルだがダサい、出来れば避けたいな
Next.jsとか流行るわけだ
職場のプロジェクトでスマートに解決してた気がする……
漁ったらaccountant + bidiを併用しているのを見つけた
記述量は増えるけどURLパラメータとかも使えるし頑張ってみるか
こうなった
結局の所は力技で全部書く部分があって、
誰が貧乏くじを引くかの違いでしかないようだ
setup-routesの部分はaccountantやbidiの威力が出ててよき
このままいこう
- tasks
- ルーターを入れる
- re-frameを入れる
- 自宅サーバーに向けてAjaxを飛ばしてJSONを受け取る
- Webアプリをガリガリ書く
re-frame を入れる
前述で社内のプロジェクトを写経している間に re-frame をついでに入れてしまったが
全体的な流れとしてはほぼ同時に実装するしかなかった
全体的な流れとしてはカマイルカ氏の記事通りにすすめていけばOK
つか、社内のプロジェクトも中身はこの記事とほぼ一緒やんな……
急いでいるのでテストやロジックは後でやろう!(死亡フラグ
- tasks
- re-frameを入れる
- 自宅サーバーに向けてAjaxを飛ばしてJSONを受け取る
- Webアプリをガリガリ書く
自宅サーバーに向けてAjaxを飛ばしてJSONを受け取る
既にWebAPIサーバーだけは用意してある
$ curl http://localhost:13000/novel/favorites | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1112 100 1112 0 0 361k 0 --:--:-- --:--:-- --:--:-- 361k
[
{
"type": "kakuyomu",
"id": "16817330662422093388",
"title": "【第2章開始!】転生チートの空間魔法使いは正体隠して目立ちたい!~国でもトップレベルの美人・美少女パーティに探されてますが、それ俺ですとは言えません~",
"page": 32,
"read": 0,
"novelupdated_at": "2023-11-05T11:03:20.000Z",
"created_at": "2023-11-05T17:37:10.000Z",
"updated_at": "2023-11-06T16:48:41.000Z"
},
...以下省略
]
後はAjaxを発射するだけ、JavaScriptにはFetchAPIがあるけど、
それ準拠でシンプルな挙動してくれるライブラリないかなぁ?
これ良さそうやん
shadow-cljsにはjs-awaitってマクロが用意されてて、Promise値を待つという事は超簡単に実装出来るらしい。
あー、でもre-frameの作りが今すぐdb
値を更新しろって感じだから、
イベント発行だけして、後はよしなにやってもらう作りと相性悪いんか
だから re-frame を使うならば re-frame-fetch-fx
を使った方が良さそう
ん〜………どっちにするかなぁ
re-frame-fetch-fx
はたらい回しにされて、
イベント宣言がアホ程増えるからあんま好きじゃないんよなぁ
今回はshadow-cljsのjs-await使ってみたいしそっちにするか
event関連は全てdispatch-syncで実装すればいいんじゃない?
clojure-lspがマクロを認識出来ずにresが宣言されてないよ!って怒ってるがまぁヨシ
こんな感じで準備しといて……
やったぜ
- tasks
- 自宅サーバーに向けてAjaxを飛ばしてJSONを受け取る
- Webアプリをガリガリ書く
感想と懸念点
腰が重くなる理由の導入の箇所を全部何とか出来たので後は実装するだけ、気が楽になった
年内を目標に少しずつ作りこんで行こうかな
ファイルは一応公開しているけど、Ajaxの送信先が非公開のオレオレAPIだから何の参考にもならない気がする……
懸念点としてはこんな感じ
- CSSのスマートな実装方法を検討・導入
- SASSを見張って即反映する (leiningenなしで実現出来るのだろうか?)
- CSS in JSならぬ「CSS in CLJS」 (検索したら結構出てきた)
- 面倒だから
:style
でよくね?
- ページ遷移
- 頑張って accountant / bidi を導入したらから多分楽勝でしょう (楽観視)
- ああ、URLパラメータの取得方法確認してない
- 同期処理・値変更時の反映
- dispatch-syncで値を更新しているから、複数のPOSTのAjaxを飛ばして値を更新する所がちと不安
- re-frameのsubscribeを使っているので問題ないと信じたい
参考資料達
shadow-cljs ユーザーズガイド
https://t-cool.github.io/shadow-cljs-users-guide-ja/docs/UsersGuide.pdf
経緯
ミーティングで「もう12月っすね」「今年のClojureのアドベントカレンダースカスカですね」「みやびさんどうですか?」という話の流れになって
アドベントカレンダーの存在すら忘れ、4年間もサボっていた事に気付く私
「じゃあなんか書きますか」って事で動きはじめた
うーん、Rustで自鯖の強化しようと思ってたんだけどな
同じものを2言語で作ってもしょうがないし別の何かを考えますか
折角Clojureを全社的に使っている会社に勤めているので
ミーティングで相談してみる
自分「やっぱりNode.jsの人間なんで、ClojureScriptでなんか作りたいですね」
自分「まだ shadow-cljs + reagent + re-frame がメジャーなんですかね?」
同僚A「そうみたい、これを超える程の構成は見てないなぁ」
同僚B「ClojureScript や shadow-cljs はトランスパイル後のJSファイルが重いから、もっとネイティブなJSに近いものを生成してくれるものも色々と登場はしているけどね」
自分「へー、とりあえず shadow-cljs でなんか作ってアドベントカレンダーに備えます」
このネイティブに近いJSファイル吐き出してくれるものも
ちらっと気になったのでググってみたものの出てこないのでもういいや
この話題を出した時点でもう12/11、名前とちょっとした使い方くらいしか知らない shadow-cljs の勉強をしないとアドベントカレンダーにはもう間に合わない
でも動機だ、動機が無いと私は何も作れない
12/15の金曜日までは動機の捻出に力を注いできた
最近 BOOX Palma というE Inkのスマホサイズのタブレットを買った
夜寝る時に布団の中へ飛び込んでスマホを眺めるとブルーライトで眠れなくなっちゃうからね
そこで問題が発生したのを思い出した
いつもスマホで読んでいる小説ブラウザとの同期が取れない
これでは布団の中でなろう小説を読んで、いつ異世界転生しても良いようにとの予習が出来ないではないか
なので最近 BOOX Palma は布団の側で転がっているだけになっている
なんとかしようと早数ヶ月、なんとかする日がついにやって来たのだ
そうだ、小説ブラウザを再現すればいいじゃん
これはNext.jsでささっと作ろうと思っていたが
獲物のLiveScriptがすっかりオワコンで言語難民生活してた所だったんだ
これをshadow-cljsでやればいいじゃん。