cycle.js というリアクティブなフレームワークが話題になっていたので試してみます。

ざっと見た感じだと、 Observable と Virtual DOM を組み合わせた感じのフレームワークのようです。 JSX も使えるようです。 React に似ている気がします。 フレームワーク自体はユニバーサルみたいですがフロントエンドの動作だけ試します。

インストール

インストールは npm で。 開発に使う Browserify なんかも入れておきます。

$ npm install -S @cycle/core @cycle/dom
$ npm install -D babelify
$ npm install -g browserify

Hello, World!

手始めに Hello, World してみます。

// a.js

//* @jsx hJSX

import cycle, { Rx } from '@cycle/core';
import { makeDOMDriver, hJSX } from '@cycle/dom';

function main({ DOM }) {
    return {
        DOM: Rx.Observable.just(<div>Hello, World!</div>)
    };
}

const drivers = {
    DOM: makeDOMDriver('body')
};

cycle.run(main, drivers);

順に見ていきます。

//* @jsx hJSX は JSX のためのコメントです。JSX をあとで import している hJSX を使った形に変換します。

Rxrx パッケージです。 Rx.Observable などを使います。

main にロジックを書きます。この場合、 Hello, World! と表示するだけの要素の Observable を作って返しています。

drivers に実際に要素を表示する先の実装を与えていきます。 @cycle/dommakeDOMDriver で実際の DOM (この場合は body) と紐つけることができます。

cycle.run でロジックと DOM を結びつけます。

Observable で DOM を返すとそれが画面に表示されます。

$ browserify -t babelify -o bundle.js a.js

このコマンドで bundle.js に変換されます。

<!DOCTYPE html><meta charset="UTF-8"><body><script src="bundle.js"></script></body>

こんな感じのテキトーな HTML で表示確認できます。Web ブラウザで開くと Hello, World! と表示されるはずです。

カウンタ

もう少しいろいろする例としてボタンを押すと表示される数字が増えるカウンタを作ってみます。

// a.js

//* @jsx hJSX

import cycle from '@cycle/core';
import { makeDOMDriver, hJSX } from '@cycle/dom';

function main({ DOM }) {
    const count$ = DOM.select('button').events('click').map((_, i) => i + 1).startWith(0);
    return { DOM: count$.map((i) => <button>{i}</button>) };
}

const drivers = {
    DOM: makeDOMDriver('body')
};

cycle.run(main, drivers);

DOM.select('button').events('click').map((_, i) => i + 1) でクリックされた数を表す Observable を作成し、それをもとにボタンを作って表示しています。 startWith で一番最初の値を 0 にしています。

Observable を組み合わせて DOM を作っていく感じみたいです。

まとめ

  • cycle.js はリアクティブなユニバーサルフレームワーク
  • Rx.Observable などを組み合わせて DOM を作成する
  • JSX も使える