最近のJavaScriptの開発と環境の基本を１からReactサーバサイドレンダリングまで１ステップずつ体得する

キーワード: JavaScript, Babel, Webpack, Koa, React

最近（たぶん）のJavaScriptの開発と環境の基本を１からReactサーバサイドレンダリングまで１ステップずつ体得するための__殴り書きロードマップ__です。
人それぞれJavaScript界隈を敬遠してきた理由はあると思います。私は半年ほど前にちょっと触ってみるかと思い立って野良記事を参考に環境構築していたところ、__当然のように書かれていたimport/export文が動かない__ところからBabel->Gulp->Webpackと次々にアイテムが現れてに一度手を引きました。
今回改めて思い立って再チャレンジし、__概念とツールが一緒くたになった日本語の与太記事に辟易__としながら、ひとつずつ整理して試しましたので、その際のメモの共有です。なぐり書きではありますが、出来合いのツールで済ませるテキトーなチュートリアルにうんざりしている人に__概念をひとつずつステップを踏んで抑えていく__ための一助になれば幸いです。

# 対象
- スクリプト言語のプログラムが書ける
- Webの仕組みは理解している
- CUIが使える
- ５年前のJavaScriptなら分かる
- ReactとかGulpとか聞いたことある気がする
- ドキュメントとStackOverflowが読める

__0からじゃなくて1からです。__PHPとかRailsやるけどnode以降のJavaScriptは眺めてきただけみたいな置いてけぼりエンジニアを想定しています。というか私が追っかけた流れをまとめ直したものです。

# ステップ
1. Nodeの環境を構築する
1. Node流モジュールで分割JavaScriptプログラムを書くる
1. ES2015流モジュールで分割JavaScriptプログラムを書いて実行する
1. Expressか素のNodeで簡単なWebプログラムを書く
1. クライアントサイドJavaScriptを分割して書いてサーバーサイドでバンドルする
1. Koa2でWebプログラムを書きなおして更に今時JavaScriptに慣れる
1. UIをクライアントサイドReactで書き上げる
1. 仕上げにReactのサーバサイドレンダリングをする
1. 周辺のことを色々抑える

# 詳細メモ
## Nodeの環境を構築する
- バージョン管理ツールの導入します。
    - 同等のものは色々あるけど悩むなら`nodebrew`でも入れておけばいい
    - 最近は`n`というのがが流行ってるぽいけど一文字の時点でやめたほうがいいたぶん絶対
    - Windowsだったら`nodist`というのを入れる
    - ポイント: `nodebrew install`より`nodebrew install-binary`で入れたほうが時間が短い
- `nodebrew`からnodeをインストールして`node`コマンドと`npm`コマンドが使えるようにします。
    - `node`コマンドは処理系。ファイル名を引けば実行する、何も引かなかればREPLが走る
    - `npm`はパッケージ（ライブラリ）管理ツール。`gem`や`bundler`や`easy_install`や`pip`と近い

## Node流モジュールで分割JavaScriptプログラムを書く
### やること
- `require`と`module.exports`を使って、`node (ファイル名)`以外の特別な作業の要らない分割プログラムを書いて実行します。
- npmを利用して何かライブラリを入れてnode流パッケージマネジメントも体得します。
    - 導入したライブラリを`require`関数を通じて利用する
    - `package.json`や`node_modules`と言ったファイル構成とnpmの`--save`や`--save-dev`オプションを理解する
- 旧JavaScriptやプログラミングに慣れていれば、nodejsを試してみた系の記事を参考にすごく簡単なのを試して見るくらいで問題ないです。
    - Class構文とかアロー関数とかはそのままで使えるはずなので試してみてみても良い

### 抑えること
- nodeの使い方
- npmコマンドかライブラリを入れてnode流パッケージマネジメントも体得します。
    - 導入したライブラリを`require`関数を通じて利用する
    - `package.json`や`node_modules`と言ったファイル構成とnpmの`--save`や`--save-dev`オプションを理解する
- 旧JavaScriptやプログラミングに慣れていれば、nodejsを試してみた系の記事を参考にすごく簡単なのを試して見るくらいで問題ないです。
    - Class構文とかアロー関数とかはそのままで使えるはずなので試してみてみても良い

## ES2015流モジュールで分割JavaScriptプログラムを書いて実行する
### やること
- まずは悲運にもモジュール化手法が乱立してしまったJavaScriptの境遇に思いを馳せます。
    - [[意訳]初学者のためのJavaScriptモジュール講座 Part1](http://qiita.com/chuck0523/items/1868a4c04ab4d8cdfb23)
        - Part2はあとで
    - [ES Modules と Node.js について - from scratch](http://yosuke-furukawa.hatenablog.com/entry/2016/05/10/111102)
- ついでに仕様だけが先走るJavaScriptに思いを馳せます。
    - ES6(ES2015),ES2016,ES.next,stage,...あたりについて策定やサポート状況をググる
    - Node.jsやio.jsの紆余曲折も余談としては面白いかも
- __純正node.jsでは実行できない__ことを理解しつつ`import`と`export`を利用した分割プログラムを書きます。
- babelというトランスパイラを利用して、純正node.jsで実行できるJavaScript（のモジュール記法）に変換します。
    - babelは、純正node.js（あるいはブラウザのJSエンジン）で実行できない未来のJSを今実行できるJSに変換するツール
    - `npm install --save-dev babel-cli`で導入、`./node_modules/.bin/自動化babel HOGE --out-dir FUGA`で変換
        - 変換用のpresetが必要なのでそれもinstallすること。
        - 単一ファイルにも出力可能(`--out-file`オプション)だがここでははファイル構成を保って変換
        - 変換後のファイルはなんとなく読めるのでざっと目を通すと良い
            - `import`が`require`に変換されているのを実感する（それだけじゃない）
    - コードの変換（トランスパイル）に際してsource mapという概念も現れるので抑えておく
    - `babel-register`とか`babel-node`とかあるけどお前にはまだ早い
- 変換してしまえば`node (変換後のエントリポイント)`で動くはずです。試してみましょう。

### 抑えること
- モジュールの現状の理解
- トランスパイラbabelの役割: トランスパイラは未来のJSだけでなく、AltJS(TypeScript)やReactJSXも今の記法に変換してくれます。

## Expressか素のNodeで簡単なWebプログラムを書く
### やること
- ググれば沢山出てくるそれを参考にして、CSS付きHello Worldを表示できる程度になぞります。
    - babelやgulpやgruntやbrowserifyやwebpackやreactを使う入門記事は害悪
    - `node`コマンドだけで実行できる範囲に収める
- Reactのサーバーサイドレンダリングをするのでその下地です。

### 抑えること
- サーバーサイドJavaScriptの基本

## クライアントサイドJavaScriptを分割して書いてサーバーサイドでバンドルする
### やること
- クライアントサイドJavaScriptの存在がJavaScriptのモジュール分割を一層ややこしくしていることに思いを馳せます。
    - [[意訳]初学者のためのJavaScriptモジュール講座 Part2](http://qiita.com/chuck0523/items/c88abe4fac828b7b5f4e)
- クライアントサイドで走らせたいJavaScript（HelloWorld程度でよい）をES2015流モジュールで書き、Babelで変換を噛ませます。
    - `node_modules/.bin/babel clientscripts -d compiledclientscripts`とか
- コンパイル済の分割コードをWebpackを利用して一つに纏めます。
    - `npm install --save-dev webpack`
    - `node_modules/.bin/webpack compiledclientscripts/main.js ./client.js`とか
- できた単一ファイルを先ほどのWebサーバを通してクライアントサイドで読込&実行できることを確認します。

### 抑えること
- クライアントサイドJavaScriptでのモジュールのバンドリングの必要性
- モジュールバンドラとしてのWebpackの利用方法、Webpack以外のモジュールバンドラの存在
- Babelの役割とWebpackの役割の違いを整理する（ちゃんとロードマップに従っていれば自明のはず）
    - 実は今回はBabelのトランスパイルは不要だった
        - __サーバー側のモジュール依存解決（実行時に参照）はNodeが行う__ので、Nodeが扱えるようにBabelがトランスパイルする
        - __クライアント側のモジュール依存解決（実行前にバンドル）はWebpackが行う__ので、Webpackが扱える形式であれば問題ない
            - WebpackはES2015 Moduleのままで扱える: [es6-loader](https://github.com/shama/es6-loader)
    - ブラウザが直接処理できない最新の記法文法やreactのJSXはBabelで変換してからバンドルする必要がある
        - 今回はこの後Reactをやることを想定して一応Babelを噛ませた

## Koa2でWebプログラムを書きなおして更に今時JavaScriptに慣れる
### やること
- Koa.jsのバージョン2の使い方をググりながら、アクセスするとHelloWorldと返すWebプログラムを書きます。
    - generatorやasync/awaitといった記法を用いる
    - とりあえず`function (ctx) { ctx.body='Hello World'; }`すればよい
        - middlewareとか今回は別にいい
    - 情報量は少ないので無理しなくても良い
- babelコマンドで変換という手順を踏んでから、nodeで実行する
    - 最先端JS記法をバリバリ使いまくるので、トランスパイルが必須
    - いちいちコンパイルするのが怠くなったら楽をする方法を学ぶ
        - `babel-node`や`babel-register`: 実行時に自動でコンパイルしてくれる
        - __クライアントサイドは関係ない__のでwebpackやbrowserifyでBabelが〜〜みたいな情報は無視すること

### 抑えること
- import/exportだけでなく最先端記法でもBabelが必要で、それぞれに応じたbabel-presetがある
- babelは事前コンパイルしなくても実行時に解決できる

## UIをクライアントサイドReactで書き上げる
### やること
- Koa.jsで静的なファイル配信できるようにします。
- Koa.jsの裏側は一旦忘れて、HTMLとクライアントJSを配信しながら[Reactのチュートリアル](https://facebook.github.io/react/tutorial/tutorial.html)をやります。
    - クライアントJSのReactコードはJSXで分割して書いてBabelコンパイル+Webpackバンドルを行う
    - 余力があればReduxに手を出してもよい

### 抑えること
- Reactを理解する
    - 思いを馳せられるようになる
        - [React.js界隈の人に聞きたい](http://anond.hatelabo.jp/20160521163144)
        - [Re: React.js界隈の人に聞きたい - mizchi's blog](http://mizchi.hatenablog.com/entry/2016/05/24/100547)

## 仕上げにReactのサーバサイドレンダリング(SSR)をする
### やること
- ReactとSSR行く末について思いを馳せます。
    - [Universal / Isomorphic JavaScript について](http://qiita.com/kyrieleison/items/4ac5bcc331aee6394440)
- あとは頑張ってください
    - ReactSSRの本筋はシンプル: `ReactDOMServer`の`renderToString`を使うことで、サーバー側でReactの描くDOMを出力する
    - SSRはサーバーサイドなのでモジュールバンドルは不要
    - Express向けだが非常に参考になる: [React + Expressでのサーバーサイドレンダリング方法のまとめ](http://qiita.com/hmarui66/items/4f75e624c4f70d596873)
殴り書き

## その他の周辺のことを色々
- ファイル変更時のの自動な再コンパイル/サーバリロード/クライアントリロード
    - node-dev, Babel/Webpackのwatchオプション, LiveReload, BrowserSync, Webpack Hot Module Replacement等
- タスクランナー（gulp, grunt）
    - [[意訳]私がGulpとGruntを手放した理由 - Qiita](http://qiita.com/chuck0523/items/dafdbd19c12efd40e2de)
- ESLint
- mochaなどのテストツール


# まとめ
ちょっと前まではAltJS/JSライブラリの戦国時代、Bower、グルグル系タスクランナー等、JavaScript開発をするにあたって無数の辟易要因がありましたが、一通り落ち着いたように思います。改めて整理してみても__不揃いな実行環境__、__モジュールシステムの乱立とバンドリング問題__、__フロントエンドUIの高度化__ぐらいに的が絞られていて、しかもどれもデファクト候補の仕組みができつつあって、だいぶ見通しが良い感じです。この他の気になることを最後に「その他周辺のこと」としてまとめてみましたが、JSに限らずどの言語にも存在する一般的なWeb開発の課題しか残りませんでした。
これからのJavaScript開発が楽しくなりそうです。Webの未来は明るい。