JavaScriptが辿った変遷
はじめに
CommonJS、ES6、Node.js、Webpack、Browserify...etc
JSの勉強してると、登場する単語が多すぎて、どうも全体像つかめません。
そして勉強していくにつれて、「これ前提知らないと分からないでしょ...」といったことが多数出てきたので、その前提を色々とまとめてみることにしました。
(わかりやすさ優先で書いています。もし不備等ございましたらコメント頂けると幸いです。)
第一部: JavaScriptの概要
JavaScriptの誕生
JavaScriptの誕生は1995年、Netscape社が、当時最も流行していたWebブラウザ、Netscape Navigatorに搭載したのが始まりです。
その後、Windowsで有名なMicrosoft社が、JavaScript のパクリ と互換性のある、JScriptなるものを開発し、今も残るInternet Explolerに搭載しました。
この両社の争いを、俗にブラウザ戦争と呼びます。
そもそもJavaScriptとは
JavaScriptとは、ブラウザ上で動く言語です。
ボタンを押したら新しくフォームが出てくるとか、そんな類の実装を行うための言語です。
そして当時、Netscape Navigatorブラウザに使われるJavaScriptと、Internet Explorerブラウザに使われるJScript(広義でのJavaScript)は、それぞれ違う仕様だったのです。(その他ブラウザ毎に仕様の異なるJavaScriptが乱立している状態でした)
これは開発者からすると面倒ですよね。
JavaScriptの標準化
その問題を解決するために、Netscape社は、JavaScriptの標準化規格を作るよう、外部機関に依頼します。 ECMA Internationalという機関です。
その結果、JavaScriptのメイン機能を標準化仕様として定義した言語、**ECMAScript(ES)**が誕生します。
そして以後は、このECMA ScriptがJavaScriptの標準規格として採用されることが多くなっていきました。
JavaScriptの言語仕様
先程挙げた「ブラウザで動く」という点以外にも、JavaScriptには色々と特徴があります。
具体的には下記が挙げられます。
- インタプリタ言語であること
- 動的型言語であること
- プロトタイプベースのオブジェクト指向であること
- イベント駆動形プログラミング言語であること
...良くわかりません。 しっくりきません。
なので、一つ一つ見ていきましょう。
・インタプリタ言語
コードを書くと、それを即座に機械が理解できる機械語に変換し、同時に処理を実行できる言語をインタプリタ言語と呼びます。
それに対して、コードを書くと、それを一括して機械語に変換したファイルを一度生成し、それを元に処理を実行するコンパイル言語と呼びます。
JavaScriptが手軽に動かせるのは、インタプリタ言語だったからなんですね。
・動的型言語
変数に型指定をしなければいけないのが静的型言語、逆に型指定をしなくて良いのが動的型言語です。
testA という変数があったとして、「これはString型の値しかいれちゃダメ!」と最初に指定するのが前者、「何でも入れていいよ! 値が入った時に考えます」が後者といったイメージですね。
これも、JavaScriptが何より手軽さを優先した結果です。
・プロトタイプベースのオブジェクティブ指向
プロトタイプベースと対比されるのはクラスベースです。この両者には、オブジェクトの生成方法に違いがあります。
前者は、プロトタイプと呼ばれる、ベースになるオブジェクトをコピーする形で新規のオブジェクトを生成します。それに対し、後者はクラスという設計図を元に新たなオブジェクトを新規作成していきます。(元々JavaScriptにはクラスという概念がありませんでしたが、後述のES6からは、新たに追加されております。)
そしてそのprototypeをベースに作られたオブジェクト単位でプログラムを構成していくので、JavaScriptは、プロトタイプベースのオブジェクティブ指向だと言う訳です。
コピー量産型言語 といった感じですかね?
・イベント駆動型プログラミング言語
「クリック」だとか「マウスオーバー」といった具合に、ある特定のイベントが発生したタイミングでプログラムが動き出す言語のことです。
なので、Webブラウザとの相性はピカイチです。
追記
JavaScriptをイベント駆動型プログラム言語と定義してしまうのはいささか語弊があるようです。
なので、あくまで「ブラウザ操作と相性の良い言語」くらいに思っていた方が安全そうですね。
第二部: JavaScriptの発展
先程ご説明したように、JavaScriptはブラウザで使う言語です。
ですが、その昔、「JavaScriptの使用範囲を、ブラウザにとどまらずもっと広範囲に広めていこうじゃないか!」 という動きが起こりました。
ですが、それを行うためには、JavaScriptには致命的な問題点があったのです。
JavaScriptの問題点
色々と問題はあったのですが、一番は、module機能の欠如です。
moduleとは、特定の処理をひとまとまりにしておくための機能のことを指します。
つまり、よく他のプログラムで見かけるような
require 'module_name' #ここで外部からモジュールをインポート
読み込んだモジュールを使用した処理
なんてことが、JavaScriptだと出来なかったわけですね。
JavaScriptの進化
「モジュールが使えない。でも、使いたい。」
そして当時の人々(2009年くらい?)は考えました。
「だったら、新しいJSの仕様を決めちゃえばいいんじゃない?」
こうして生まれたのが、CommonJSです。
CommonJS
CommonJSと聞くと、「JSのライブラリかな?」「どんな記法なんだろう?」なんて思われる方もいるかと思うのですが、CommonJSはあくまで仕様の名前です。
日本の法律に日本国憲法と名前がついているように、新しいJSの仕様にCommonJSと名前がついている。という話ですね。
そしてこのmodule機能が使える(もちろん規格なので、他の機能に関した決まり事も存在しています)CommonJSの仕様に従って、新たなJavaScriptの仲間が誕生します。
Node.js
Node.jsとは、サーバーサイドのJavaScriptです。
先ほどJavaScriptはブラウザサイドの言語だというお話をしましたが、新たにCommonJSという仕様が出来たお陰で、サーバーサイドでもJavaScriptを使用することが出来るようになったのです!
そしてこのNode.js、なかなか流行ります。
すると今度は、「Node.jsを使ったツール」が色々と開発されるようになります。
その結果、必然的にそれを管理するバージョン管理ツールが必要となってくるという流れになります。
※追記
現状、CommonJS制定⇒Node.jsが出来る⇒Node.jsがゴリゴリ独自開発⇒その独自開発に多言語が追随 という流れがあり、このNode.js独自実装が事実上のCommonJSとして取り扱われているみたいです。
npm
先ほどの経緯で作られた、Node.js製ツールのバージョン管理ソフト です。
Node.js製のツールは、このnpmを使って管理されます。
bower
こちらは、jQueryやAngularJSなど、従来のブラウザで動くJavaScript用パッケージのバージョン管理を担うツールです。
npmとよく混同されることが多いので注意してください。
第三章: JavaScript使い分け問題と、その対応
経緯
CommonJSに従って作られた新たなJavaScriptは、既存のJavaScriptのように、ブラウザ上で動くわけではありません。
ですので、せっかくNode.jsで作られた便利なツール達が、ブラウザ上では使えなかったのです。
でも、使いたいですよね?
ビルドツール
CommonJSのrequire機能(外部モジュールの読み込み)を、ブラウザ上でも有効にするためのツールです。
このビルドツールの登場により、CommonJSに準拠して作られたツールが、ブラウザ上でも使えるようになったのです。
代表的なものとして、browserifyやWebpackなどが挙げられます。
タスクランナー
Gulp、Grunt、guard...etc
この辺りの調べ物をしていると、これらの名前に行き着くことも多いのではないですか?
これらはタスクランナーと呼ばれ、JavaScriptのコードを書いてから、実際にブラウザで使えるまでの諸々の作業を自動化してくれるツール達です。(新JSをブラウザで使用するには色々と手間が掛かったのでしたね...)
先程も登場したWebpackなんかは、このタスクランナーの要素も含んでるみたいです。
難読化
JavaScriptのファイルは、誰でもブラウザから簡単に見えてしまいます。
その為、「うちのソースパクられたくないんですけど」といった要望が出てきます。
それを叶えるのが難読化という作業。
動作はそのまま、ファイルを、人の目では分かりづらくしてくれる作業のことです。
代表的なツールとして、ugilifyなどが挙げられます。
ちなみに、この難読化前の情報をもったファイルをmapfileと呼び、デバッグ時などは、このmapfileを元に行います。
minify
JSファイルの不要な空白等を省き、ファイルサイズを小さくすることを指します。
この作業により、画面の読み込み速度UPが期待出来ます。
第四章: 一方その頃ECMAは
JavaScriptの標準化規格作成を依頼されたECMA International。
第一弾が出来てから、その後どうなったのかと言うと...?
ECMAScript2016
その標準化されたECMAScriptシリーズの最新版がこのECMAScript2016です。(2016年9月現在)
ES2016、またはES7などとも呼ばれていて、色々と新機能が追加されているそう。
また、その一つ前のES2015では、classの概念やletによる変数定義など、便利な機能が色々と追加されているのだとか。(追加された機能に関してはこちら)
色々とJavaScriptも新しくなっていってるんですね...!
ちなみに、このES6、ES7に対して、旧JavaScriptはES5と呼ばれています。
ES7策定による新たな問題
新しい物が出来ると、やっぱり何かと問題が起きるものなんですねー。
今度は、**「新しい構文に、既存のブラウザが追いつかない」**問題が発生します。
さぁ、ここでも救世主の登場です。
トランスパイラ
ES7やES6の構文で書かれたJavaScriptを、現在のブラウザで使用可能なES5に直してくれるツールのことです。
その代表格がbabel。
このbabelを取り入れることで、ブラウザがES7やES6の構文に対応する前から、それらの構文で書いたコードをブラウザ上で動かすことが出来るようになりました。
第五章: トランスパイル言語とライブラリ
最後に、いくつかJavaScriptを中心とした兄弟言語を紹介していければと思います。
AltJS
「JavaScriptを、もっと簡単に使いたい!」
といったニーズから、AltJSなるものが生まれてきます。
これらは、JavaScriptに似た(より簡単な)言語でコードを記述することで、内部的にJavaScriptに変換されたて実行されるというものです。(この変換の作業をトランスパイルと呼びます。)
具体的には、下記などが挙げられます。
CoffeeScript
- Railsに採用されてる。
- 後述のES6がCoffeeScriptの特徴を盛り込んでるので、「だったらES6で良くね?」⇒オワコン な予感らしい。
TypeScript
- 静的型言語 = 変数に型が使える
JSX
- Reactで仮想DOMをXMLで扱う為に使用。
Dart
- Googleが開発を進めてる。
代表的なフレームワーク
rubyにRailsというフレームワークがあるように、JavaScriptにもフレームワークが存在しています。
そのうち、代表的なものをいくつかご紹介します。
jQuery
- フレームワークと言いながら、いきなりフレームワークではなくライブラリの類のものw
- ちょっとしたDOM操作を行うならこれで十分。歴史も古いし文献も多い。
- Bootstrapとかの有名所でjQueryに依存してるもの多い。
React
- Facebook社が開発。
- viewに特化したフレームワーク
- 仮想DOM採用。早い
- Viewだけのライブラリなので、他に比べて学習コスト少ない気がする
AngularJS
- Google社が開発
- MVW(Model・View・Whatever)という設計モデルを採用
- フルスタックライブラリ
- 最近2.0がリリース。仮想DOM採用(2016年9月現在 http://angularjs.blogspot.jp/2016/09/angular2-final.html)
Backbone.JS
- 軽量、シンプル
- 自由度が高い
- 使ったこと無いのであんま分からない 笑
まとめ
さぁ、これで大方のJavaScript界隈の流れをご説明出来たのではないかと思います。
今後ますますES6やCommonJSの仕様に従った実装が増えてくるかと思いますので、今のうちに全体像の整理や、記法への慣れなど取り組んでみてはいかがでしょうか?
Discussion
Thanks for sharing this article and the great explanation of the JavaScript world! I've discovered lots of essential details. I recently came across another interesting article about popular JavaScript frameworks, so you might also find it helpful.