JavaScript
Node.js
reactjs
React
React #1Day 14

ReactとJavaScriptとASTと

Pete Huntとテンプレートエンジン

Pete Huntはblogを持っていました。その名も「Pete's tech blog」。直球です。Pete Huntがblogに初投稿したのはPythonエンジニアだった2010年3月23日。今から7年以上も前のことです。次のようなタイトルでした。

"なぜ私はほとんどのテンプレートエンジンを好きではないか"

初投稿から攻めたタイトルです。大まかな主張は次のようなものです。

Pete Huntの主張

  1. モダンなフレームワークはテンプレートエンジンがベース
  2. テンプレートエンジンはMVCのひとつの実装例で、MVCは関心の分離のひとつの実装例
  3. しかしVにCが入るテンプレートエンジンは関心の分離を達成できていない
  4. MVCではなく、MVMC(Model-View-Markup-Controller)にすべき
    • マークアップにロジックを埋め込まず、Pythonでマークアップを操作すべき
    • (テンプレートエンジンの)pullモデルではなく(DOMの)pushモデルに転換しよう
  5. そのためのツールは既に存在していて、PyQueryとPyMeld(meld3)

Pete Huntがそこまで言うPyMeldとPyQueryとはなんなのでしょうか。

PyMeld

HTMLをPythonオブジェクトに変換して操作するライブラリです。

>>> page = Meld('<html><span id="x">Hello world</span></html>')
>>> print page.x
<span id="x">Hello world</span>

DOM文字列をPythonオブジェクト化して、Pythonオブジェクトとして扱っています。Real-world exampleを見ると、その様子がより具体的にわかります。

PyQuery

XMLをjQueryライクに操作できるライブラリです。PyMeldが通常のPythonのオブジェクトの操作のようにDOMを操作するのに対して、PyQueryはjQueryライクに操作する点が違いでしょうか。

いずれにせよ、テンプレートエンジンをpullして値を入れるのではなく、ネイティブな言語(Python)の強力さを使ってDOMを構築してpushしています。

PythonからReactへ

Pete Huntは、blogの初ポストで 「テンプレートエンジンのDSLによってではなく、ネイティブな言語によってDOMを操作しよう」 「ネイティブな言語で作成したDOMをHTMLにpushしよう」 と主張し、これはReactの萌芽ともみて取れます。

ただし、入力がHTMLの文字列である点、PyQueryは内部DSLへの依存度が高い点、再描画の効率性や冪等性はどうするのかなど課題は多々あってReactのような完成度には至っていません。Pete Huntの提案を実装に落とし込むときに、SPAも流行ってきていたこの時代にPythonでは十分とはいえません。そして実際に、JavaScriptやNode.jsに興味を持っていきます。

"Node.jsについて"

Node.jsの創始者Ryan DahlがFacebookで講演を行った影響を受けて書いた記事です。Pete HuntはHacker Newsの熱心な読者で、当時活発に投稿されていたNode.jsのspamのような記事にうんざりさせられていたようでした。しかしながら、Ryan Dahlの話を聞いて興奮し、Node.jsの設計の美しさに感銘を受けたようです。PythonのTwistedで上手くできないこともNode.jsならできると判断し、将来的に現実のプロジェクトにNode.jsを導入すると宣言します。

"テンプレート言語は有害と考えられる"

初回投稿から1年半後に、テンプレートエンジンに関してまたしてもこのような投稿をしました。

ダイクストラの論文のタイトルに倣ったこの投稿では、

templating languages have no valid use cases

とさらに強烈な主張をしています。Pete Huntが他の何よりも照準を合わせているのがテンプレートエンジンであることはもう明確です。XHPにも言及しており確証を得ているのでしょう。

この前後では、Node.jsやJavaScriptを賞賛し「仕事でPythonを使うことをやめたのでPyMySQLのメンテナを探す」宣言をしています。

そして、2年後の2013年。Reactは発表されました。

React発表後のPete Huntの講演

Pete Huntのテンプレートエンジン批判はblogだけに止まるところを知りません。講演にも関わらず30分のはじめの10分くらいはテンプレートエンジン批判を繰り広げています。

jsconf1.png

言語の発散と集約

「関心の分離」といった設計論は抜きにしてもテンプレートエンジンを導入すると外部DSLが登場し、記述言語が発散するのは事実でしょう。

一方、ReactはJavaScriptによるViewの構築や操作をフロントエンドにもたらしました。CSSですらJavaScriptで統制できます。

ReactとJavaScriptとASTと

JavaScriptによってViewを制御できるようななった結果、viewを 単一のAST として統一的に扱える時代が到来しました。JSXを含めてもASTとしては、ESTreeの十分小さな拡張となっています。

JavaScriptは、ASTの実験場の様相を呈していて、強力なツールが多々登場しています。ReactはASTがJSXを含めてもJavaScriptの十分小さなスーパーセットであるが故にこうしたツールを比較的容易に適用できます。よく使いそうなツールを列挙してみます。

AST操作ツール

静的解析/フォーマット

  • ESLint:静的解析を行うツール
  • Prettier:eslintなどのコード規約を元に自動フォーマット。ASTを固定して中間表現を操作して生成。

私のプロジェクトでは、gitのcommit時に自動でESLintとPrettierをかけて、通らないとコミットできないようにしています。

リファクタリング

  • JScodeshift: コードの変換規則(codemod)を元にして、コードを変換。ライブラリのAPI変更時にコードを安全に自動変換する目的で作られたが任意に利用可能。

  • React-codemod: JScodeshiftのReact用のcodemod集。

最近だと、React.PropTypesからprop-typesに変更になった時に使った人も多いのではないかと思います。

XcodeでもSwift等のAPIの大きな変更がある際にこうした機能が追加されています。今後のライブラリや言語では、API変更時にはASTベースの移行ツールと"codemod"が提供されるのが、標準になるのではないでしょうか。

まとめ

Pete Huntがテンプレートエンジンを批判してから7年、彼の思想を込めたであろうReactはフロントエンド開発のライブラリのトップクラスの人気を獲得するに至りました。そして、ReactによってフロントエンドのViewは単一の言語で記述できるようになり、JavaScriptの豊穣なAST操作ツールの恩恵を簡単に受けられるようになりました。

ReactによるViewの圏とECMAScript(の十分小さい拡張)のASTの圏とはbabylonやbabel-generatorやrecastなどの共変関手によって圏同値になったとも言えるかも知れません。十分に良い性質を持った圏と同値なViewは、ユーザーが望むと望まざるとに拘わらず、強力なASTツールの影響下におかれます。

テンプレートエンジンのDSL等との和集合をとったASTが人気を獲得することもある可能性もゼロではありませんが、それは良いASTになっているでしょうか。比較的新しいVue.jsでもこの点に気づいたのか、テンプレートエンジンではなくJSやJSXを使えるようになってきてはいます。

これからは強力なASTツール群との親和性の高さという観点で、Reactを選択しておくのも一案ではないでしょうか。私のプロジェクトでも、ESLint、Prettier、codemodなどの恩恵に預かっている他、babylon等によって、

  • アプリケーションのUIコンポーネントやテーマなどを動的に交換・変更
  • SwaggerのSpec変更時に、React/FluxやNode.jsのバックエンドの関連コードを自動修正

といったことを実施していて、ネイティブな言語によってViewを記述・制御する強力さを改めて実感しています。

さらに、近い将来「特徴量としてのAST」という概念が盛り上がってフロントエンドに本格的に機械学習が適用されると推測していますが、これをもっとも実現しやすいWebのフロントエンドは現時点ではReactでしょう。

Reactによって我々はWebのフロントエンドを単一のASTとして簡単に操作できるようになりましたが、その結果可能性が広がって達成すべきことも大量に残っていると実感しています。Pete Huntたちがどこまで考えていたものかはわかりませんが、ReactによってWebのフロントエンドの未来は明るいものになったのではないかと思います。