TL; DR
-
gcanti/elm-ts
というライブラリがあり、fp-tsでElm Architectureを実装している - elm-tsは
virtual-dom
の代わりにReactを使っているがPluggableである- >
React
instead ofvirtual-dom
(pluggable) - しかし、具体的にどのように他のVirtual DOMの実装を使えばよいか具体的な記述はない
- この記事ではPreactを使う場合の具体的なやり方を紹介する。おそらく同じやり方で他のVirtual DOMの実装(snabbdom-modulesなど)も使うことが出来るはず
- >
やり方
一言で言えば、elm-ts/lib/React
の Html
インターフェースの代わりにPreact Compatibleな Html
インターフェースを自前で定義して使えばok。
/**
* `Dom` is a `ReactElement`.
* @category model
* @since 0.5.0
*/
export interface Dom extends ReactElement<any> {
}
/**
* `Html` has `Dom` type constrained to the specialized version for `React`.
* @category model
* @since 0.5.0
*/
export interface Html<Msg> extends html.Html<Dom, Msg> {
}
elm-ts/lib/React
の Html
インターフェースの定義はこんな感じなので、Dom
(=ReactElement<any>
)をPreact相当のものに差し替えればよさそう。
// Instead of Html, use PreactHtml
export type PreactHtml<Msg> = Html<h.JSX.Element, Msg>;
よしなにview functionの定義で PreactHtml
を使う。
export function view(model: Model): PreactHtml<Msg> {
return <div>...</div>
}
あとは program
を run
するだけだが、React.program
を使うことはできないので elm-ts/lib/Html
の program
を次のようにして使う。
import { programWithDebuggerWithFlags } from "elm-ts/lib/Debug/Html";
import { Flags, Model, Msg, flags, init, update, view } from "./App";
import { programWithFlags, run } from "elm-ts/lib/Html";
import { VNode, h, render } from "preact";
// React.programはもういないんだ
const program = process.env.NODE_ENV === "production" ? programWithFlags : programWithDebuggerWithFlags;
// もうあの時間は終わって、君も人生と向き合う時なんだ
// programのGenericsの4つ目にpreactの VNode を使っているところに注意
const main = program<Flags, Model, Msg, VNode>(init, update, view);
const app = document.getElementById("app");
if (app === null) {
throw new Error("id=appな要素がない");
}
run(main(flags), dom => render(dom, app));
おわり。
おことわり
- elm-tsはできて間もないライブラリなので仕様がすぐ変わり、このやり方では動かなくなるかも
- 公式のREADMEにPRを出さずにBlog Postにした理由はこれ
Top comments (0)