LoginSignup
79

More than 5 years have passed since last update.

Reactに最適化したテンプレートエンジンを作り始めた

Last updated at Posted at 2015-04-18

Reiny, 名前の由来は、一昨日の木曜日に作り始めて、その日雨が降ってたから。

最近react-jadeに不満を持ってて、自分はコンパイラというかプリプロセッサを作るノウハウはあるので、だったら自分で作ればいいじゃん、といった感じで作り始めた。(typed coffee を作り直すためのAST操作の勉強も兼ねてた)

何ができるか

今これが動いてる

- let i = () => {};
div(hoge='fuga') {
  backgroundColor = 'red'
}
  // unicode
  span(
    key="--🐑--"
  )

  // ref with &
  span&foo()

  // for syntax
  ul
    for i in @items
      li(key=i) = i

  // if syntax
  if false
    a hoge fuga aaa

  // inline expression
  if { 2 > 1 }
    a(key='fooo') hoge fuga aaa

  // text
  | aaaa bbbb

  // object mixin as property
  - let o = {'data-a': 'aaa', 'data-b': 'bbb'};
  foo(
    > o
    onClick = {- function(){console.log('foo')} -}
  )

テンプレートをコンパイルすると、reactの仮想DOMを生成する関数を生成する。一種のaltjsのようなもの。reinyのruntimeと一緒に使う。 

詳しくは reiny/example at master · mizchi/reiny をみてほしい

長所

基本的にはjadeのシンタックスはそのままに、インラインでコードを書けるようにした。そしてインラインコードはbabelでプリプロセスされるので、es6のコードが書ける。 (本当はif文やfor文のexpressionでも使いたかったのだが、自前でes6パーサが必要になるので後回し)

他のテンプレートエンジンと比べた際の最大の特長は、インラインのstyle記法にシンタックスを一個割り振ってる。(Reactのstyle: {} に相当)

.foo&refName:keyName(
  id = 'foo'
) {
  backgroundColor = 'red'
  fontSize = { 4*4 }
}

インラインスタイルは賛否あるが、Reactでグリグリ動かす際にはcssクラスの付け替えるのはJS書く目線だと結構面倒くさくて、特にposition:absolute 下でのtopやleftのJSで触る値については完全に完結できるようにしたかった。ゲームとか作ってる人は欲しいと思う。

普段はscssを使っているのだが、ほぼ同じツリーを二度書いている感覚あって、だったらここで全部書けてもいいのでは、という感じ。おそらく、自分の用途だとマークアップエンジニアと連携するときは最小限に抑えるが、自分で書くときはここにベタに書くだろうなァという気がしている。

gfmと同じように\` 3つで複数行のコード書けるようにしたんだけど、markdownにやさしくなかった…

react-jade の不満

jadejs/react-jade

基本的に良く出来てて、それなりに枯れてそうに見えるのだけど、元がreact用ではないjadeをベースに無理やり拡張しているので、細かい不満がある。

  • 複数行にまたがるインラインコードが書けない
  • React環境下でロジックをたくさんテンプレートエンジンで書かないといけない状態で、生のJSが辛い
  • 引数としてオブジェクトが渡せない (MyComponent(obj) が出来ない)

基本的には枯れてるreact-jadeを使えばいいと思うのだけど、不満があったらreinyの方も見て欲しい。といった感じ。

なぜJSXではダメか

jsxはエンジニアに寄りすぎて少なくともデザイナには無理だし、そもそも読み易くない(と自分は思っている)。独自パーサなので他のaltjsにもやさしくない。reinyは生産性と拡張性のそのあたりのバランスを取りたい。

gulp / browserify 用プラグイン

gulpプラグインとbrowserifyプラグインは作った。

あとはとりあえずatom用のシンタックス定義でも作るか、という気がしている。

現状

  • Babel決め打ちになってる部分を、オプションで他のコンパイラを選べるようにする
  • 細かい部分が枯れてないので、ドッグフーディングする

とにかくエッジケースを潰してないので、ドッグフーディングして潰す。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
79