モダンJSの簡単まとめ

# はじめに

個人的に全体像の把握のために、勉強した内容をざっくりまとめただけなので、詳細の正しさなどは担保していない備忘録として作成。

# モダンJSとは？

ES2015（JavaScript の 2015 年バージョン）以降の JavaScript を指していると思われます。
特にモジュール機能の獲得こそが JavaScript のモダン化にとって最も重要な要素だと考えられます。

## モダンJS前に発生していた問題

### 名前空間や依存関係によるバグ

他のプログラミング言語では名前空間を自由に設定できることが多いですが、残念ながらJavaScriptでは名前空間は１つしかもつことができません。そのことから、同じ命名の関数が被ってしまうことが頻発しました。
また、読み込み順などにより発生する依存関係でのトラブルも頻発しており、JavaScriptは衰退していきかけました。

しかし、この解決してくれたのが、
**モジュール**と**npm**でした。

簡単にいえば、

**モジュールは名前空間の問題**を解決し
**npm（パッケージ管理）は依存関係の問題**を解決してくれました！！

ここらへんからモダンJavaScriptになっていったと考えていいですね。

## 何を伝えたいか？

ブラウザでモジュールを使うために模索した結果、
コードを事前に変換することが主流となった。コードを事前に変換するとモジュールを使える以外にも恩恵があること。


## Node.jsの誕生

Node.jsは2009年に誕生。最初はCommonJSのモジュールAPIに準拠。
しかし、CommonJSのコミュニティーがうまく機能しなくなり、
Node.js独自の進化を遂げていく。

## パッケージ管理システム

サーバーサイドでモジュールが使われるようになると、
次にほしくなるのはパッケージ管理システム

そもそもパッケージとは？

packege.jsonで記述されたファイルやディレクトリのこと。
共有したい機能の単位とも言える。

パッケージ管理システムは大きく分けると以下の機能を持っている
1. リポジトリの購読
2. パッケージのインストール・削除
3. 依存関係の解決
4. 設定管理


リポジトリの購読
ローカル環境にインストールしたパッケージを更新できる。また検索したりできること

依存関係の解決
パッケージに必要な別のパッケージを自動的にインストールしたり、更新したりできること

設定管理
設定を書くことで１、２、３を自動化できる。
毎回手動でパッケージを入れたりする必要がなくなりチームでの環境を簡単揃えたりできる。


## npmの誕生

**Node Package Manager**の略で、元々はNode.jsのパッケージ管理ツールとしてうまれた。

パッケージを手動でインストールするのは非効率。
パッケージをいい感じにインストールしたり、管理できるのがパッケージ管理ツール。

**ここまではサーバーサイドの話・・・フロントエンドは解決していない。**

### 事前にブラウザ向けに変換するという流れが起きる

フロントエンド側でも様々な取り組みがあったようですが、満足できるものがないなかで
大きなパラダイムシフトが起きる。
それが、「事前にブラウザ向けに変換をする」ということで、
書いたコードと動くコードが違うということです

## ビルド
書いたコード→**ブラウザ向けに変換**→ブラウザで動くコード
という流れができるわけです。
この**ブラウザ向けに変換をしてくれる行為**こそが**ビルド**になります。


そしてその時に出てきた概念が

Bundle（バンドル）
Compile（コンパイル）という二つの概念です。


### Bundleについて

正式な文章ではないですが以下のようにまとめます。

1.CommonJSモジュールを開発
2.モジュールの依存関係を事前に解決して１ファイルに変換（これがバンドル）
3.変換したコードをいつも通りScriptタグで読み込む

この考え方によってそれを実装した１つのバンドルツールができあがります。
それが Browserigyというものです。

結局何ができるようになったかというと

ブラウザでもBrowserifyを使うとrequireを使うコードが使用できるようになったということです。
これにより、ブラウザでもrequire構文を用いて、モジュール開発ができるようになり、Node.jsのパッケージがブラウザ向けに移植されることになりました。

Node.jsのパッケージ管理ツールであるnpmにたくさんあったパッケージがBrowserifyを通すことでブラウザ側でも使用できるようになり、ブラウザでもnpmが使われるようになった。

そして現在では、その上位互換にあたるバンドルツールの「Webpack」が2012年に誕生し主流となっています。

![スクリーンショット 2021-02-21 12.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515053/bcd9e436-d850-17cf-a93f-bec39ba1e70b.png)

ここで大切なのは

Browserifyはcjs形式のモジュールをバンドルするのに対して
Webpackはどんな形式でもバンドルするということです。

### Webpackを使う理由
- モダンでないブラウザでモジュールを使う為
- http通信を一括で行う為
- コードの最適化(１行でまとめてファイルサイズを小さくする)のため
- プラグインの追加
- いろんな種類のファイルを扱う為
- HMR(保存した瞬間に同期される)付きのローカルサーバーを使う為

### ES Modules　の誕生

今までのモジュール開発というのは、common.jsや何とかブラウザ向けにモジュール開発できないかと半ば強引に変換をしたりしていたわけで、JavaScriptそのものがもっている仕様というのはなかった。
しかし、ここで遂にES ModulesというjavaScript独自のモジュールの使用が誕生する。

ただし、この段階ではIEなどのブラウザの対応がされていなく、サポートがなかったため、Webpackなどのモジュールバンドラーが必要だという流れは変わっていなかった。

つまりこの段階ではES Modulesを使用してブラウザで表示するためにはWebpackなどモジュールバンドラー必要だったってこと。

### WebpackがES Modulesをネイティブ対応化

Webpack version2でES Modulesをネイティブ対応かするという対応をしたおかげで、
ES Modulesを使用したいという需要に答え、Webpack一強の時代となります。

## Compileのお話

もう一つの概念であったCompileを使うと

1.開発時ではブラウザでは使えないけど開発に便利な機能を使ってコードをかける
2.書いたコードをブラウザで動くように変換する（これがコンパイル）
3.変換したコードをいつも通りScriptタグで読み込む

ここで混乱するので１つまとめておくと

バンドルはモジュールを利用する際の依存関係の処理に焦点を当てたもの
コンパイルはモジュール以外の便利な機能を使う際の処理に焦点を当てたもの

ES２０１５でモジュール以外にも
let,const,class,Promiss,アロー関数,分割代入,スプレッド構文,テンプレート文字列...など沢山の使用が追加された。（これがコンパイルの際に使いたい便利機能）

### Babelの誕生

これを解決するために出てきたのがBabel。
ES２０１５などで書かれたコード（モジュール・便利機能を利用したって意味）を従来の環境でも動くように古いJavaScriptに変換するコンパイラ。

#### Webpackと一緒に使えた。
Webpackの設定でbabelを一緒に使うことができた。
これによって、モジュールが使えるようになるだけでなく、ES２０１５の便利機能も使えるようになり、JavaScriptが便利になっていった。


#### これによっていろんなパッケージが流行り出す

React(.jsx)
Vue(.vue)
TypeScript(.ts)
など、現在主流になっているもの。これがコンパイルによって使えるようになっていく。


## 今回の流れで大切なことまとめ

ブラウザでモジュールを使うことを模索した結果、**事前にコード*を変換することが主流になる。

パラダイムシフト
過去
Scriptタグでjqueryを読み込む→ブラウザで動くコードを書く→当然ブラウザで動く

現在
開発でモジュールや便利機能を使い開発→バンドル・コンパイルによって事前にブラウザで動くjsファイルに変換→ブラウザで動く

この流れが非常に大切なこと。