歴史を知ると現在と未来が見える
今回は「フロントエンドの歴史」です。この記事は以下の人に向けた内容になります。
- フロントエンドエンジニアを目指してモダンフロント(ReactやVue.js)を始めたばかりの人
- モダンフロントでWebpackが使われている理由がわからないまま作業している人
- JQueryを学ぼうか迷っている人・モダンフロントを使う意味や価値がわかるようになる
プログラミングを学習するときに歴史を学ぶ必要があるのでしょうか。私はあると断言できます。
技術の移り変わりには理由があり、当時の悩みと解決策が繰り返されています。
その結果、今があり、未来につながっていきます。今と未来を正確に見るためには過去を知る必要があります。
フロントエンド界では「書いたコードを事前にサーバーサイドで変換してからブラウザに表示させる」という大革命が起こりました。
なぜ大革命なのか、フロントエンドは何に困っていたのかを知ることで、以下の3点がわかります。
- WebpackやBabelの意味を理解して使用できる
- 今後の技術変遷の流れを掴むことができる
- 現在最適な技術選定を考えられるようになる
これらができるようになると、ただコードを書くだけではないエンジニアになれます。
歴史を知ることで今を知り、未来を考えるきっかけにして、一歩進んだフロントエンドエンジニアを一緒に目指していきましょう。
全体像を捉える
まずは全体像をみておきましょう。
フロントエンドは3つの時代にわかれていると私はとらえています。
- 画面に動きをつける時代
- アプリケーションの規模の拡大期
- 保守性とユーザー体験向上時代
大きな流れを捉える上で大事なのは、始めは画面に動きをつける程度しか期待されていなかったJavaScriptが、アプリケーションの規模拡大とともに役割が増えてきたことです。
そして現在、表示速度の向上や保守性の高さなど役割は更に拡大しています。
JavaSctiptの役割が増えることによってエンジニアが何に悩みどうやって解決してきたのか流れをみていきましょう。
画面に動きをつける
動きをつけたい
HTMLとCSSでウェブ上に画面の表示ができるようになった後、求められたのはリッチな動きでした。
ガラケーからスマホへのような、もっといいものが欲しいという流れがあったわけです。動きを出すユーザーの要望に対する答えの一つが「JavaScript」でした。
ブラウザ間の差をなくしたい
JavaScriptによって動きが出せるようになったものの、問題がありました。ブラウザ間の相互互換性が低いことです。
現在で例えると、chromeでは動くのにsafariでは動かない状況があったのです。
なぜなら、この当時ブラウザの提供事情者がそれぞれ独自に機能拡張していたからです。
不便で使いにくい状況から脱却しようと、JavaScriptの規格を統一する動きができました。
この標準規格化されたJavaScriptを「ECMAScript」といいます。しかし、ブラウザ間の差を完全に埋めることはできませんでした。
ES2015とは「2015年」に発表された「ECMAScript 」のことをいいます。
アプリの大規模化
JavaScriptを簡単に使いたい
JavaScriptにはもう一つの問題がありました。記述が長くなり非常に使いにくいことです。そこで登場したのが「JQuery 」です。
JQueryの登場により、膨大に記述していたJavaScriptを少量で済ませることができるようになりました。
さらにブラウザ間の差を吸収してくれることもあり、JavaScriptライブラリのデファクトスタンダード(お前なしではJavaScriptは使えないぜ状態)と呼ばれるまでに人気を得ました。
画面読み込みしたくない
この頃になるとアプリの規模が大きくなりだし、JavaScriptに求められる要望も広がります。その一つが「画面を読み込まずにデータを取得して表示したい」です。
Google Mapが画面を変えるたびにページを読み込んでいたらイライラして使い物になりません。Twitterで「いいね」するたびに読み込まれても同様です。この悩みを解決したのが「Ajax」です。
Ajaxは別途詳しく解説します。今は「JavaScriptを使ってデータを取得し、画面を読み込まずに表示できる技術」という理解で十分です。
Ajaxのおかげでできることが広がり、アプリはますます大規模化されていきます。
サーバーサイドでJavaScriptを使いたい
Ajaxの登場でJavaScriptの人気は高まると「サーバーサイドでもJavaScriptを使いたい」という要望が広がります。
これまではサーバーサイドはRuby、フロントエンドはJavaSctiptのように完全に別の言語で構成していました。
両方ともJavaSctiptで書けたら「学習コストは下がるし、言語を置き換えて記述しなくていいから便利だ」と思う人が増えたのです。
そして、「サーバーサイドでJavaSctiptを使おう」プロジェクトが始まります。これが「CommonJS」です。CommonJSは言語ではなく、プロジェクトの名前です。
CommonJSによって定められた仕様に基づいて作られた言語がNode.jsです。CommonJSという仕様によって、サーバーサイドでJavaSctiptが使えるようになりました。
【これまでのまとめ】
- JavaSctiptは画面を動かすことを目的につくられたため、限定的な使用を想定
- アプリの大規模化によって、JavaSctiptに求められるものが増加
- 簡単に使えるJQuery、画面読み込みせずに表示できるAjax、サーバーサイドでJavaSctiptの利用
名前空間の問題を解消したい
名前空間とは何か
「関数や変数の名前が影響する範囲」を名前空間といいます。
名前空間を家族に当てはめて考えてみましょう!
家族の中で同じ名前の人はいないですね。
家族の中で同じ名前の人がいると、誰のことかわからなくなり不便だからです。このとき名前空間は家族なので、家族内で同じ名前はつけられない決まりになります。
同姓同名の人が別の家族にいても問題ないのは、名前空間が分かれているからです。
家族Aの「山田太郎さん」と家族Bの「山田太郎さん」は家族Aと家族Bの名前空間にそれぞれ属しているため、同じ氏名でも独立性を確保しているのです。
なぜ名前の重複が問題になるのか。意図しない関数や変数が呼び出されてエラーが起きるからです。「ちょっとJavaSctiptを使おう」であれば名前空間を気にすることなく使うことができました。
しかし、アプリの大規模化によりファイルを分割し、複数人で開発するようになると「同じ名前」を「別の人」が「別の場所」でつくってしまう問題が発生します。
すると意図しない書き換えが起こり、バグが発生します。
AMD・RequireJS・ESモジュール
名前空間の問題を解決するためにできたのが、AMDとRequireJSです。AMDはブラウザ側で名前空間のと依存関係(後述)を解決するための仕様です。
仕様に基づいて作られた言語がRequireJSです。
一方で、「JavaSctipt自体にモジュールの仕組みが欲しい」という要望がフロントエンド界にありました。この要望からできたのが「ESモジュール」です。ESモジュールはES2015で追加された機能の一つです。
モジュールとは「1つのファイルのこと」です。モジュール単位で名前空間がわけられるようになったため、名前の重複がなくなります。
しかし、ESモジュールをすべてのブラウザで使用できるわけではなかったため、WebPackのようなモジュールバンドラーが発達することになります。
依存関係の問題を解消したい
アプリの大規模化による2つ目の問題は依存関係です。依存関係とは「一つの要素が他の要素に影響を与えること」です。
例えば「僕は彼女なしでは生きられない」となれば「僕は彼女に依存している」といえますね。
同じことがプログラミングでも起こります。BはAを前提に組み立てている場合、BはAに依存しています。「BはAなしには動かない」状況です。
依存関係の何が問題になるのか。アプリが大規模化して複数のファイルを読み込む時、順番を間違えると動かなくなってしまうことです。
当初JavaSctiptは「ちょっと動きをつける使い方」を想定していました。そのため、ファイルは1つで、複数に分割して管理することは想定されていませんでした。
しかし、アプリが大規模化して膨大な記述量になり、1つのファイルで管理が難しくなると複数のファイルで管理するようになります。このときに依存関係を考慮しないとバグが発生するのです。
クライアントサイドからのアプローチ
名前空間の問題で登場したAMDとRequireJSにより、依存関係の問題も同時に解消されつつありました。そうなると、次にパッケージの依存関係の問題が発生します。
パッケージとは「一つの機能をなすモジュールの集合体」です。Railsを学習した人であればログイン周りの機能を提供するDeviceを利用したことがあるのではないでしょうか。
ログイン機能を構成するモジュールの集まりがDeviceというパッケージになります。パッケージの依存関係を解消するために「Bower」が誕生しました。
しかし、クライアントサイドとサーバーサイドの重複管理、バージョンを指定して管理できないなどの問題があったため、パッケージはサーバーサイドでまとめて管理していく流れになっていきます。
依存関係には「モジュール」と「パッケージ」の2つがあります。パッケージの依存関係の管理には「Node.jsはnpm、laravelはcomposer、Railsはbundler」などがあります。
サーバーサイドからのアプローチ
サーバーサイドではパッケージを管理する仕組みがすでにありました。Node.jsのnpm(Node Pakage Manager)です。
npmを使ってクライアントサイドとサーバーサイドのパッケージを管理しようとした時に革命が起こります。「クライアントサイドのモジュールの依存関係の解消をサーバーサイドで行ってしまおう」という考え方の大転換です。
これまでは、AMDとRequireJSによってモジュールの依存関係問題を解決していました。
この常識を壊し、開発はCommonJS形式のモジュールで行い、サーバーサイドで依存関係を解決して1つのファイルにまとめてしまおうとしたのです。
そこで登場したのが「WebPack」です。WebPackはNode.jsのパッケージの一つです。
CommonJS形式で書かれたモジュールの依存関係を解消して1つのファイルにまとめてくれます。
複数のファイルに分かれて作成したjsファイルを1つのjsファイルに依存関係を解決した上でまとめてくれるため、ブラウザで使用するときにはまとめられたファイルを読み込むだけ済みます。
サーバーサイドでモジュールの依存関係を解決し1つのファイルにまとめることを「バンドル」といいます。
ESモジュールが登場するとWebPackは対応したため、ESモジュール形式でもWebpackが利用できるようになっています。
保守性とユーザー体験の向上
もっと便利にJavaSctiptを使いたい
アプリケーションの規模拡大が一定程度進むと、保守性の高さ、開発速度が求められます。そのためには、より便利にJavaSctiptを使いたくなります。
その解決法が「Babel」です。Babelは「便利に使える機能を、ブラウザで表示できるように変換」します。このことをコンパイルといいます。
例えば、ES2015ではconst・let、スプレッド構文、アロー関数などの様々な機能が導入されました。しかし、ブラウザ側がサポートしていない場合、これらの機能は使えません。
BabelがES2015の構文で記述されたコードを昔の形式にコンパイルしてくれるおかげで、エンジニアはES2015の新機能を使えるのです。
他にもReactの.jsx、Vue.jsの.vue、typescriptの.tsで書かれたものもコンパイルしてブラウザで表示できるようになっています。
BabelはWebpackの設定で導入することができるので、急速に普及していきました。
ReactやVueでWebPackを導入して、事前にコード変換しているのは、.jsxや.vueは直接ブラウザで表示できないため、コンパイルする必要があるためです。このときに合わせてモジュールの依存関係も解決しています。
ストレスフルを実現したい
スマホが普及したことにより、ユーザーがアプリケーションに触れる機械が劇的に増加しました。読み込み時間が長いとユーザーがすぐに離脱してしまうようになります。
携帯初期のiモードのときのように数秒かけて読み込むのをじっくり待つ世界観ではなくなっています。
そこで登場した技術が「SPA(シングルページアプリケーション)、SSR(サーバーサイドレンダリング)、仮想DOM」です。
これらの技術は説明すると長くなるので、別途説明します。大事なのは、ユーザー体験を向上させるために、既存の仕組みから考え方を大きく変えたことです。
まとめ
最後にまとめていきましょう。JavaSctiptは大きく3つの時代に分かれます。
- 画面に動きをつける時代
- アプリケーションの規模の拡大期
- 保守性とユーザー体験向上時代
アプリケーションの規模拡大に伴い、JavaSctiptに求められる要求も大きくなりました。そこで登場した技術が以下の3つでした。
- JQuery:より簡単にJavaSctiptを使いたい
- Ajax:読み込みせずに表示させたい
- Node.js:サーバーサイドでJavaSctiptを使いたい
当初想定していたよりもJavaSctiptの使用範囲が広まった結果、2つの弊害が起こりました。
- 名前の重複
- 依存関係
クライアントサイドではこの問題をAMDとRequireJSで解決し、パッケージの依存関係をBowerを使って解消しました。
しかし、様々な問題があったため、「WebPackを使ってサーバーサイドでモジュールの依存関係を解決する」という方針に大きく転換しました。ここがフロントエンドの大革命です。
アプリケーションの拡大が一定程度進むと、保守性の高さや開発速度が求められたため、便利な機能をブラウザで表示できる形に変換するBabelが普及しました。
React やVueがブラウザで表示できるのはBabelが変換してくれるからです。
ユーザー体験を向上させるために、SPA、SSR、仮想DOMといった新たな技術が登場して、ストレスのないWebページが実現されるようになってきています。
最後までお読みいただきありがとうございます。最初に全体像をざっくり把握すると今自分が何をしているのかが見えてきます。
フロントエンドの歴史にリアルタイムで参加できるなんてワクワクします。これからも一緒に学習していきましょう。ではまた!
※わかりやすさを重視しているため、正確性にかける部分がありますので、詳しくは書籍などを読んで学習をすすめていただければと思います。
コメント