bouzuya.hatenablog.com

ぼうずやのにっき

わりと何をしたのか分からない日

なんだか疲れている。

fgb (private) にコマンドをひとつ追加した。あと bouzuya/tamaruSSR を諦めて SSR で追加された要素を消した。ちょっとした DOM 操作でさえつらい。

わりと何をしたのか分からない日だ。いつもどおりに仕事した。↑のように申し訳程度にソースコードも書いた。何かしらしているけど、モヤモヤする。直近の何をしたのか分からない日は 2018-05-18 らしい。毎月のように分からなくなっているんだなあ。

今日はズートピアが地上波で放送されていたらしい。検索してみたら、ぼくは 2016-05-30 に観たようだ。偏見を裏切るようにできている、かあ。

bouzuya/tamaru では halogen の server-side rendering を諦める

bouzuya/tamaru 。 halogen で server-side rendering を諦めたほうが良いかもしれない……。 Halogen.VDom.DriverrunUI を触っていたときにそんな気はしていて、見ないようにしてきたんだけど。今日ついにそこに到達した。

今日は client-side の entry point を見ていた。試してみたところ server-side での結果を再利用できそうにない。

Halogen.VDom.DriverrunUI は↓を見れば分かるけど void $ DOM.appendChild node (DOM.htmlElementToNode container) している。最初に DOM へ反映させるとき、指定した container へ組み立てた要素を appendChild するだけ。

https://github.com/slamdata/purescript-halogen/blob/923c5a4d3f46d17c5abf888647179c482e3465d4/src/Halogen/VDom/Driver.purs#L127

何を気にしているのかというと、既存の DOM を考慮してくれないということ。 React で言うところの hydrate 的なアレがなさそう、ということ。これをなんとかするのは骨が折れそうだ。 server でつくった状態へと halogen-vdom の machine を持っていけると良いのだけど、 Halogen.VDom.DriverrunUI にはそういう口がない。おそらく Halogen.VDom.Driver モジュールを作り直すことになるだろう。せっかく 2018-06-11 によって回避できた 2018-06-09 の問題が再燃する。

もう tamaru では……、せっかく HTML をつくれるところまではやったけど……、諦めて container の子を remove してしまおうかと思っている。次のプロジェクトでなんとかするか、あるいは halogen を捨ててしまうか……。それはまだ分からない。 bouzuya/fwt では Component -> String さえできなかったが、 tamaru ではできた。次はさらに進めるかもしれない。

bouzuya/tamaru の static file を配信する / 髪を切った

今日は fgb (private) に機能追加。 Backlog API で User Activity を取得している。

bouzuya/tamaru 。昨日 (2018-06-12) の fileServer の件に着手。とりあえず、雑にファイルを返すようにした。きちんとつくれば、切り出してほかのプロジェクトでも使えそう。 Node.* に依存しているのが嫌だな……。今回のこれは簡易なものなので良いとして、静的なファイルは S3 に置いて CloudFront 経由で配信するほうが良いと思う。


2018-W24 は 3 の倍数週なので、髪を切った。前回は 2018-05-23

bouzuya/tamaru はまだ static な file を配信できない

bouzuya/tamaru 。今日は GroupListDataList に値を入れて表示するところまで。

server-side rendering ができたと喜んでいたのだけど、 client-side rendering (のための script の配信) ができない。 static な file を配信する機能がない。前回の bouzuya/fwtowickstrom/hyperfileServer を使っていた。今回は hyper じゃないので、どうするか……。


今日は通院に付き添う。順調そうだ。

Halogen の Component を今度こそ String にする話

何度か書いてきた。 slamdata/purescript-halogen の Component を String にする話。過去の記事は↓あたり。

Halogen の Component を String にしたい。 server side rendering する際に Component をそのまま使えると (実行効率はともかく) 何度も書かなくて済む。こんなことくらい当然のように書いてあると思いきや、情報がなくていろいろ模索した。さんざん苦労したのに Component をバラす方法に変えたら、あっという間に動いてしまった。

細かい説明は面倒なので、ソースコードを示す。

https://github.com/bouzuya/tamaru/blob/f2692c82ffd295958f8a5212b0c0f035435af719/src/Bouzuya/Halogen/StringRenderer.purs

module Bouzuya.Halogen.StringRenderer (render) where

import Halogen as H
import Halogen.HTML as HH
import Halogen.VDom.DOM.StringRenderer as VSR
import Prelude (Unit)

render
  :: forall f i o m
  . H.Component HH.HTML f i o m
  -> i
  -> String
render = componentToString

componentToString
  :: forall f i o m
  . H.Component HH.HTML f i o m
  -> i
  -> String
componentToString component input =
  H.unComponent
    (\{ initialState, render } ->
      let (HH.HTML vdom) = render (initialState input) in
      VSR.render componentSlotToString vdom
    )
    component

componentSlotToString
  :: forall f g m p
  . H.ComponentSlot HH.HTML g m p (f Unit)
  -> String
componentSlotToString slot =
  H.unComponentSlot
    (\_ component input _ _ _ -> componentToString component input)
    slot

雑に言うと unComponentunComponentSlot を使って Component やその子である ComponentSlot をバラして、あとは Halogen.VDom.DOM.StringRendererrender に食わせる。バラしたものは initialStaterender そして input くらいしか使わない。 initialStateInput -> StaterenderState -> HTML ...inputInput 。あとはその組み合わせ。

苦労が嘘みたいに簡単だった。まだ何か漏れていそうだけど。

2018-W23 ふりかえり

2018-W23 をふりかえる。

2018-W23 の目標 とその記事

目標。

  • ☑ bouzuya/bs のことを書く
  • ☑ bouzuya/bs-code v2.0.2 をつくる
  • ☐ bouzuya/tamaru v1.0.0 をつくる

記事。

目標は一部達成。 bouzuya/tamaru はあまり進んでいない。 halogen の component の render で時間を食っている。今日また進展があったので、明日にでも書く。

つくったもの

2018-06-04/2018-06-10

bs-code は目標にあるとおり v2.0.2 へ。先週アップデートした bouzuya/bs を使って不具合を直した。

tamaru は 1.0.0 にいまだ到達できず。理由は↑にもある halogen の SSR

よんだもの

(なし)

組織論』は返却してしまった。最後まで読めず。

みたもの

2018-05 から週 2 本の制限がある。今週は OK 。

昨晩は『スター・トレック』を観た。 2009 年の映画。過去のシリーズをまったく知らないのだけど、たぶん「収まるべき形におさまってめでたし」というオチだったんだろうな、アレで。

その他

土日は妻と出かけている。土曜日は暑い中を、日曜日は妻の親戚と食事、そして買い物。

今週は Halogen の Component の render に困っていた。……ところが、今日やったら、あっさりと問題を解決できたような……。詳細は明日また書く。

腕立て伏せを継続している。回数は伸びていない。来週あたりからスクワットを追加しそう。

2018-W24 の目標

  • bouzuya/tamaru v1.0.0 をつくる
  • Halogen の Component を String にする話をまた書く

Halogen の Component を String にできない話の続き

bouzuya/tamaru 。些細な点にこだわりすぎて進んでいない。

昨日 (2018-06-08) の子 Component の描画に対応しようとしていた。結論から書くと、ぼくにはまだできなかった。 RenderSpec を雑に実装している点と slamdata/purescript-halogen-vdom-string-renderer を組み合わせている点がまずそうだ。

どこで詰まっているのかを整理するため、ぼくの現状の実装について書く。

ソースコードhttps://github.com/bouzuya/tamaru/blob/9e258b97640d978e76fcd9570fa5a03f3474c0a0/src/Server/ComponentRenderer.purs

halogen は通常 Halogen.VDom.DriverrunUI を使用して動かす。これは実 DOM (DOM.HTML.Types.HTMLElement) に対して指定した Component を描画し、動かしていく。この runUI は内部で Halogen.Aff.DriverrunUI を使用している。こちらの runUI へ実 DOM に依存していないので、ぼくはこれを使っている。

ぼくの現在の実装は、この Halogen.Aff.DriverrunUI へ実 DOM に依存しない適当な RenderSpec を与えることで文字列として描画しようとしている。この RenderSpec の組み立て方がよく分からないのだけど、大切なのは render くらい。……くらいと書いたが、↓みたいな型になっていて、ぼくみたいのには「よく分からない」以上の感想が出てこない。

render
  :: forall s f g p o
   . (forall x. InputF x (f x) -> Eff (HalogenEffects eff) Unit)
  -> (ComponentSlot h g (Aff (HalogenEffects eff)) p (f Unit) -> Eff (HalogenEffects eff) (RenderStateX r eff))
  -> h (ComponentSlot h g (Aff (HalogenEffects eff)) p (f Unit)) (f Unit)
  -> Maybe (r s f g p o eff)
  -> Eff (HalogenEffects eff) (r s f g p o eff)

これを雑に説明すると↓のとおりだ。

  • Component への Query を処理するハンドラー
  • 子要素を描画するハンドラー
  • 要素
  • 前の RenderState

Halogen.VDom.DriverrunUI では、これを halogen-vdom でつくれる「実 DOM を更新していく machine 」や描画結果の実 DOM を返す RenderState で実装している。

ぼくはまともに machine や RenderState を用意していない。最初に渡される要素を Halogen.VDom.DOM.StringRendererrender に与えていた。

ここまでが現状の実装。で、何が問題なのか。

Halogen.VDom.DOM.StringRendererrender は↓のような型だ。

render ∷ ∀ i w. (w → String) → VDom (Array (Prop i)) w → String

w というのが halogen-vdom の Widget だ。ぼくはこれがほとんど使われないものかと思っていたので const "" という適当な値にしていた。しかし、実際には halogen の子 ComponentComponentSlot を使用しており、それはすべて Widget なのだった。

たぶん、まともに machine を実装し Halogen.VDom.DOM.StringRenderer を捨てるか、強引に ComponentSlot をバラして render する関数 (w -> String) を実装すればなんとかなると思う。どちらも地獄っぽい。


今日も出かけた。わけあって暑い時間帯に出かけることとなった。暑すぎて、ひどく汗をかいたし、疲れた。

2018-05-31 にも書いたけど、この数週間で土日に出かける頻度が増えており、思ったように進まない。↑も断片的に調べるせいで、何がなんだか分からなくなっている。

おまけに明日も出かけるんだよな……。