質問: ### ご挨拶 閲覧ありがとうございます。業務経験4ヶ月、それ以前は趣味だけでWEBに触ってきた超初学者です。 至らない点等多々あると思いますがご教授お願いいたします。 ### 経緯 最近(それほど最近じゃないのかもしれませんが)、ReactやVue.jsなどのJavaScriptフレームワークの名前をよく耳にします。 エンジニアの求人とか見てても、現場の使用技術にも書かれてたりしますよね。 ReactやVueが何者調べてみると、部品(「コンポーネント」?)などの使い回しができたり、通常のJavaScriptでDOMをイジるより早かったりと、「ああ、便利なんだなぁ」と思いながら調べ進めている時にどうしても納得のいかない、というかイメージが全く沸かない点があったのでご教授頂けると幸いです。 抽象的な部分でイメージがつかないので、いくら調べてもチュートリアルを読んでもパッとしません。 ### 分からない事 上記フレームワークはMVCモデルもしくはMVVMモデルと一緒に語られる事が多いと思います。(私の調べた限りでは) **しかし、ReactもVue.jsも、あくまでもブラウザ(=フロント)ですよね・・・?** 私の知ってるMVCモデルは、(RoRしか触ったことありませんが...) 1. サーバーのフレームワークでURIをルーティングし、 2. コントローラーで受け、 3. コントローラーは、モデルを使ってデータを出し入れしたり、処理したりして、 4. コントローラーはビューにデータを渡して 5. ビューでは、コントローラーから渡されたデータを元にテンプレートエンジンやらなんやらでHTMLを構築して、クライアントに返す というものです。 「ブラウザはあくまでも、サーバーから渡された物を描画するだけ、 たまにJavaScriptが、画面に動きつけたりXHRでちょっとしたデータを取ってきたりするためのもの」 だと思っていました。 おそらくこの固定観念のせいで理解に詰まっているのだと思いますが、まったくイメージが湧きません。 クライアントでMVCとは何なのでしょうか? 逆にクライアント側でそこまでやるとサーバーは何を仕事にするのですか?(クライアントがそこまでやるなら、サーバーは何をレスポンスすれば良いのですか?) 「無くて困ってないなら無理して使わなくて良いものだ」とは思いつつも、ここまで広く使われてる物がまったくイメージがつかないのも如何なものかとも思い、どうかご教授頂けますと幸いです。
回答: > > クライアントでMVCとは何なのでしょうか? > > > そもそもMVCは欠陥品なんで忘れましょう。 Modelの役割デカすぎじゃないですか、大規模なシステムだと大概破綻してますよね? しかもControllerの役割理解出来てない人多すぎ、コントロールに注力しろよみたいな。 Webサーバですら「ごらんの有様」なのに、 フロントにまで持っていこうとするとシッチャカメッチャカになります。 なのでどのJSフレームワークもMVCとは名乗っていないはずです。 > > 「ブラウザはあくまでも、サーバーから渡された物を描画するだけ、 > > たまにJavaScriptが、画面に動きつけたりXHRでちょっとしたデータを取ってきたりするためのもの」 > > > ここもう少し掘り下げましょうか。 ブラウザが描画するものは基本的にHTMLが起点となります。 HTMLを解析し、周辺情報(CSS、画像、JSファイル)を集めてページを描画します。 JavaScriptが「HTMLを後から修正し」画面の変更を促します。 このブラウザがHTMLを解析し、描画される前にDOMツリーというルールで組み立てまして、 JavaScriptはこのDOMツリーを動的に編集するんですけどね。 そしてJSフレームワークの学習にあたってもう一つの軸であるRestfulにも触れておくべきでしょう。 何となくWebサーバはHTTPリクエストが来たらHTMLファイルを返す存在として定着していますが、 本来のRestfulやCRUDの思想から言えば、純粋なデータだけを取り扱いたいものです。 何故ならばHTMLが糞フォーマットだから。 いや、HTML自体はXMLの前身にもなっている整合性の取れた優れた文書形式なんです。 CSSの表現能力が足りず、デザインの都合がHTMLに及ぶのが糞なんです。 XML・JSON・CSV・HTMLとデータを表す文書フォーマットは沢山ありますが、 「そうだ、画面が古臭いからデザインを更新しよう」という動機でフォーマットが壊れるのはHTMLだけです。 という訳で、RestfulやCRUDのWebサーバの実装がHTMLを返すというのは 【アウトプットのフォーマットがコロコロ変わる糞なサーバ」を意味しているわけですね。 なのでHTMLではなく、XMLやJSON・CSV等を返すように仕様を変更したい。 RailsはRestfulやCRUDを表現するフレームワークですよね。 RailsがCRUDに真に集中する為には、テンプレート越しにHTMLを返すのをやめた方が都合が良いのです。 そしたらデザインの一新でテンプレートに手を付ける必要はなくなりますからね。 この辺の都合があり白羽の矢がたったのが、 動的にHTMLを編集できるJavaScriptです。 これにより、最初はガワだけ作っておき、裏でAjax通信を飛ばして、 その結果を元に画面をJavaScriptで作るというのが流行りました。 この辺が2003年のGoogleMapで流行り、2006年にjQueryというライブラリが登場して盛り上がったジャンルです。 また2006年にJSONというファイルフォーマットも定義され、 今まで読み書きが大変だったXMLやCSVに置き換わっていきました。 しかし、JavaScriptのDOM APIは手続き型のDOM操作なので冪等性がありません。 A→BのDOM変更を行うJavaScriptコードを書く事は出来ました。 しかし、既にBのDOMに同じモノを適用して、同じコードを走らせたらDOMツリーが粉微塵に吹き飛ぶという危険を孕んでいます。 それを回避する為に、世のフロントエンドエンジニアは日夜Excelで作ったテスト項目書を片手に夜遅くまで動作検証を行っていたわけですね。 辛い。 ここからようやく本題のJSフレームワークです。 フレームワークにより思想ややることは少しずつ違いますが、以下が共通点です。 * JSフレームワークにテンプレートとなるHTMLを読み込ませる * JS世界の変数を正として、フレームワーク推奨の手法で値を書き換える 実際のDOMツリー構造は、JS世界の変数を変更した瞬間に、 その値に相応しいあるべき姿(最新のDOMツリー)に置き換わります。 もし短い時間で値が書き換わり、2回更新作業が走っても、 2回最新のDOMツリー構造が払い出されるだけ。 フロントエンドエンジニアは冪等性を手にし、変数世界の値を監視するだけで良くなりました。 ページが表示されたら裏側でHTTPリクエストを飛ばし、 値が戻ってくるタイミングでJSフレームワークのお作法に従って値を書き換えテンプレートを更新させます。 こうすることでRoRはJSONやXML、CSVを返す綺麗なCRUDサーバとして運用し、 フロントだけでHTML+CSS+JSで動作する汚いビューの部分を全て受け持つ事が可能になりました。 そのフロントのビューの部分も、テンプレートと関数が並んでいるだけで、 あるべき姿を書いてテストしていくという、冪等性を駆使したプログラミングが出来るようになってきています。 > > URIをルーティング > > > これもJavaScriptで行うことも増えましたね。 2014辺りからぼちぼち流行りだしたSPA(シングル ページ アプリケーション)です。 先程説明したJSフレームワークに読み込ませるHTMLテンプレートというのは、 好き勝手に縦割りで分割出来ます。 なのでURLに従ってテンプレートを用意してJSフレームワークに流し込み、 それをURL毎に出し分ければルーティングすることも可能です。 JSフレームワークにはそれ用のルーティングライブラリもあるので、簡単にSPAを実現することも可能です。