mithril.js v1.0 の変更点

こんにちは。DeNA Games Osaka 技術編成部のさい(@sairoutine)です。
DeNA Games OsakaはDeNAの大阪拠点です。今後ともよろしくおねがいします。

2017年01月31日に、mithril.jsのv1.0がリリースされました。 (2017年5月現在、v1.1.1までリリースされています)

軽い/高速/低学習コストというmithril.js本来の特徴はそのままに、これまでのバージョンでは制約となっていた機能が大幅に変更されています。

本記事では、v1.0のリリースに当たって、大きな変更となる箇所をご紹介したいと思います。
なお、mithril.js自体の紹介については、下記の記事をご参照ください。

最速フレームワーク Mithril 入門
http://developers.mobage.jp/blog/mithril-introduction

JSX が推奨に

仮想DOMのHTML like な独自拡張構文として React には JSXがありました。同様に、mithril.js にも MSX というのがありましたが、MSX は 1.0 から非推奨になり、公式のドキュメントでも、babel と transform-react-jsx が推奨となりました。

m.deferred が廃止され、Promise が使用される

v0.2.5 までは m.deferred という Promise like な非同期処理のための関数があり、m.request 等の一部の関数は m.deferred を使用していました。これが v1.0 からはブラウザネイティブな Promise を使用するようになりました。Promise 非対応ブラウザではpolyfill を使用してくれるので、引き続き IE9 までの古いブラウザでも、mithril.js が使用できることに変わりはありません。

m.prop が廃止され stream に

v0.2.5 までは、(主に Model)クラスのプロパティの getter/setter を作成するために m.prop という関数がありました。 v1.0 からはこれが廃止され、stream という命名で別モジュールに切り出されました。

stream では今までの getter/setter 機能に加えて、stream から新しい stream を生成して、元の stream の内容の変更を新しい stream に伝播させたり、あるいは stream 同士の合体をすることができるようになりました。

// stream から新しい stream の生成
var value = stream(1)

var doubled = value.map(function(value) {
    return value * 2
})

console.log(doubled()) // 2

// stream の合体
var firstName = stream("John")
var lastName = stream("Doe")
var fullName = stream.merge([firstName, lastName]).map(function(values) {
    return values.join(" ")
})

console.log(fullName()) // "John Doe"

firstName("Mary")

console.log(fullName()) // "Mary Doe"

streamモジュールは他にも色々と出来ることがあるので、詳しくは公式ドキュメントの stream の項を参照頂ければと思います。

vnode の概念の追加

v1.0 から vnode (Virtual DOM nodes)という概念が追加されました。vnode とは仮想DOMツリーを表すオブジェクトです。コンポーネントの view 関数や、あるいは後述するライフサイクルイベントに定義された関数が mithril から呼ばれる際に、引数として渡されます。

例えば、コンポーネントに状態を持たせて、状態を参照したり変更したりしたい場合は、vnode.state に状態を追加/変更します。

var Component = {
    oninit : function(vnode) {
        vnode.state.fooga = 1
    },
    view : function(vnode) {
        return m("p", vnode.state.fooga)
    }
}

vnode オブジェクトは他にも色々なプロパティを持つので、詳しくは公式のドキュメントの vnode の項目を参照頂ければと思います。

ライフサイクルイベント

v0.2.5 までは、仮想DOMに対する config 属性で一部のライフサイクルイベント(oninit, onupdate 等)に対する処理を実装していました。v1.0 からは config が廃止され、コンポーネントに対して、以下のライフサイクルイベントで処理される関数を定義することができるようになりました。

oninit
コンポーネントが初期化される際に呼びだされるフックです。実DOMが追加されるより前に呼び出されます。

oncreate
oninit と異なり、oncreate はコンポーネントが初期化されて、実DOMが作成した後に呼び出されます。実DOMが作成した後に呼ばれるため、vnode.dom 経由で実DOMを取得して操作を行うことが可能です。

onupdate
mithril.js による再描画によって、一度生成された DOMに更新があると呼び出されます。onupdate が呼び出された際には、既に更新された実DOMが生成されているので、vnode.dom 経由で更新後の実DOMを取得したり、操作することが可能です。

onbeforeupdate
onupdate と同様に、一度生成されたDOMに更新があると呼び出されます。onupdate が、更新された実DOMが生成された後に呼ばれるのに対して、onbeforeupdate では更新された実DOMが生成される前の、仮想DOMの差分比較のタイミングで呼び出されます。この時、onbeforeupdate で定義した関数でfalse を返すことで、差分検知をスキップすることができます。

onbeforeremove
DOMが削除される前に呼ばれます。このタイミングでは、削除される実DOMはまだ削除されていないので、vnode.dom で実DOMにアクセスすることが可能です。また、onbeforeremove で定義した関数がPromise オブジェクトを返すと、mithril.js はそのPromise が完了するまで、実DOMの削除を遅延します。

onremove
DOMが削除される際に呼ばれます。onbeforeremove に関数が定義されていると、onremove は onbeforeremove が完了した後に呼び出されます。

controller の廃止

controller という概念がなくなり、今まで controller のコンストラクタで行っていたことは、コンポーネントの oninit で行うことが推奨されました。またコントローラに紐づく関数は、コンポーネントの関数として記述することが推奨となりました。

最後に

v1.0 アップデートに当たっての大きな変更点をご紹介させていただきました。その他にも細かい変更がありますので、詳細は公式の change log を参照頂ければと思います。

コンポーネントに対するライフサイクルイベントの追加や、あるいは controller の廃止により、所感としてMVC フレームワークというより、コンポーネント指向なフレームワークに近くなった印象です。

一方で、軽い/高速/低学習コストという mithril.js 本来の特徴は失われていません。 SPAを構築する上で充分かつ必要最小限なAPIに加えて、他のライブラリやビルドツールに対して低依存であることから、JSフレームワークにおけるスイスアーミーナイフのような存在です。

v1.0 にアップデートされた mithril.js にぜひ一度皆様も触れてみてください。

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る