まるノート

備忘録も兼ねて、様々なお役立ち情報をまとめています。

JavaScriptの歴史 ~CommonJSとES2015~

はじめに

maru-note.net

上記の記事ではJavaScriptの誕生から2015年までの経緯を記載しました。

  • 2009年の「Webブラウザで動くJavaScriptをサーバーサイドでも使いたいという需要」
  • 2015年の「第6版からは表記を改め、ES2015として年号が使われるようになり、大幅な機能追加が行われる」

について少し掘り下げて見ようと思います。


2009年頃のJavaScript

まずは2009年頃の出来事について、当時の状況やJavaScriptが抱えていた問題点からCommonJSの誕生、 そしてモジュール機能について見てゆきます。


状況

サーバーサイドでの利用需要や急速な発展にも関わらず、従来Webブラウザ上に動きを付けるために作られた言語だったため、当時のJavaScriptには様々な機能が不足していました。

中でも不足点として他のJSファイルを取り込む標準的な仕様が存在しなかったということが挙げられます。


サーバーで用いられるような大規模なファイルを扱う場合、通常は機能ごとにファイル分割をして複数人で開発をすすめることになります。


分割したファイルや、外部JSファイルを読み込みたい場合、以下のようにHTMLファイルにscriptタグを書き込むことで別ファイルを読み込んでいました。

以下のようなイメージです。

<script src="js/hoge_1.js"></script>  //  hoge.js を分割したファイル
<script src="js/hoge_2.js"></script>  //  hoge.js を分割したファイル
<script src="js/hoge_3.js"></script>  //  hoge.js を分割したファイル
<script src="js/vender/fuga.js"></script>
<script src="js/vender/fuga-ui.js"></script> //  fuga.js を前提に作られたファイル


このようにファイルが分割されていたり外部ファイルを読み込んでいる場合、
単純に上から順にファイルの読み込みが行われます。


問題点

① 変数名が被っていた場合、後から読み込んだファイルの変数名で上書きされてしまう。
→ 命名の衝突をさける為の名前空間と呼ばれる概念がない

② あるファイルをもとに別のファイルが作られていた場合、一方を修正するともう一方の処理が想定どおりに動かなくなってしまう。
→ 依存関係を解決する仕組みがない


こういった問題を解決するためCommonJSと呼ばれるプロジェクトが発足し、様々なAPI仕様が作られてゆきます。
①の問題については、この時に作られたモジュールAPI仕様が解決することになります。

モジュールについて モジュールとは、実態としては単なるファイルですが、外部ファイルの読み込み/書き出しを行う仕組みの上で利用され、上の例にあるような分割した機能ごとのjsファイルをさします。

※CommonJSはあくまでサーバーサイドでJavaScriptを扱うための仕様であり、Webブラウザで利用する場合には依然として、モジュールAPIを利用することは出来ませんでした。


モジュールを読み込む方法(CommonJS)

CommonJS に従って作られた新たなJavaScriptでは、 export、require 機能が使えます。

export について、モジュール側はmodule.exportsに関数やクラスなどを定義します。

/* module.js */

module.exports = function() {
    console.log('Hello World!');
}

読込む側はrequire([先ほどのモジュールを定義したファイルパス])で読み込みを行います。

/* main.js */

const helloWorldModule = require('./module.js');
helloWorldModule();
// 出力:Hello World!


上述した通り CommonJS はサーバーサイドでJavaScriptを扱うための仕様でなのでブラウザ側ではrequire文は使えません。


2015年頃のJavaScript

第6版のES6からは表記を改め、ES2015として年号が使われるようになり、大幅な機能追加が行われます。


ES2015について

以前までのJavaScriptとは仕様が大きく変わり、主に以下の内容が可能になります。

  • Javaのようなclass定義
  • import/export文によるコードのモジュール化
  • letとconstによる変数の宣言
  • IteratorとGeneratorのの導入
  • Promise,Map,Set,Proxy等の組み込みオブジェクト利用
  • String,Number,Array等の既存組み込みオブジェクトの利用

ここで注目して頂きたいのは、import/export文によるコードのモジュール化です。
これにより今までブラウザ側では使えなかったコードのモジュール化が可能になりました。


モジュールを読み込む方法(ES2015)

同じ export でも CommonJS のものとは記法が違い、モジュール側では通常通り関数やクラスを定義し、頭にexportを付けます。

/* module.js */
export const helloWorld = function() {
    console.log('Hello World!');
}

読み込み側ではimport文を使って先ほどのモジュールを読み込みます。

/* main.js */
import { helloWorld } from './module'
helloWorld();
}


おわりに

以上が2009年、2015年のJavaScript界隈の主な出来事です。
この時期のJavaScriptの出来事や周辺知識について記事に出来ることはたくさんあり、自分自身勉強中です。

また今回触れていないのですが、特に2009年のCommonJSの制定後に出来たNode.jsの誕生は、サーバーサイドJavaScript別の発展に大きく影響している内容です。
こちらはまた別の記事で取り上げようと思います。