キーワード: JavaScript, Babel, Webpack, Koa, React
最近(たぶん)のJavaScriptの開発と環境の基本を1からReactサーバサイドレンダリングまで1ステップずつ体得するための__殴り書きロードマップ__です。
人それぞれJavaScript界隈を敬遠してきた理由はあると思います。私は半年ほど前にちょっと触ってみるかと思い立って野良記事を参考に環境構築していたところ、__当然のように書かれていたimport/export文が動かない__ところからBabel->Gulp->Webpackと次々にアイテムが現れてに一度手を引きました。
今回改めて思い立って再チャレンジし、__概念とツールが一緒くたになった日本語の与太記事に辟易__としながら、ひとつずつ整理して試しましたので、その際のメモの共有です。なぐり書きではありますが、出来合いのツールで済ませるテキトーなチュートリアルにうんざりしている人に__概念をひとつずつステップを踏んで抑えていく__ための一助になれば幸いです。
対象
- スクリプト言語のプログラムが書ける
- Webの仕組みは理解している
- CUIが使える
- 5年前のJavaScriptなら分かる
- ReactとかGulpとか聞いたことある気がする
- ドキュメントとStackOverflowが読める
__0からじゃなくて1からです。__PHPとかRailsやるけどnode以降のJavaScriptは眺めてきただけみたいな置いてけぼりエンジニアを想定しています。というか私が追っかけた流れをまとめ直したものです。
ステップ
- Nodeの環境を構築する
- Node流モジュールで分割JavaScriptプログラムを書くる
- ES2015流モジュールで分割JavaScriptプログラムを書いて実行する
- Expressか素のNodeで簡単なWebプログラムを書く
- クライアントサイドJavaScriptを分割して書いてサーバーサイドでバンドルする
- Koa2でWebプログラムを書きなおして更に今時JavaScriptに慣れる
- UIをクライアントサイドReactで書き上げる
- 仕上げにReactのサーバサイドレンダリングをする
- 周辺のことを色々抑える
詳細メモ
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に思いを馳せます。
- 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(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
- ブラウザが直接処理できない最新の記法文法やreactのJSXはBabelで変換してからバンドルする必要がある
- 今回はこの後Reactをやることを想定して一応Babelを噛ませた
- 実は今回は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のチュートリアルをやります。
- クライアントJSのReactコードはJSXで分割して書いてBabelコンパイル+Webpackバンドルを行う
- 余力があればReduxに手を出してもよい
抑えること
- Reactを理解する
- 思いを馳せられるようになる
仕上げにReactのサーバサイドレンダリング(SSR)をする
やること
- ReactとSSR行く末について思いを馳せます。
- あとは頑張ってください
- ReactSSRの本筋はシンプル:
ReactDOMServer
のrenderToString
を使うことで、サーバー側でReactの描くDOMを出力する - SSRはサーバーサイドなのでモジュールバンドルは不要
- Express向けだが非常に参考になる: React + Expressでのサーバーサイドレンダリング方法のまとめ
殴り書き
- ReactSSRの本筋はシンプル:
その他の周辺のことを色々
- ファイル変更時のの自動な再コンパイル/サーバリロード/クライアントリロード
- node-dev, Babel/Webpackのwatchオプション, LiveReload, BrowserSync, Webpack Hot Module Replacement等
- タスクランナー(gulp, grunt)
- ESLint
- mochaなどのテストツール
まとめ
ちょっと前まではAltJS/JSライブラリの戦国時代、Bower、グルグル系タスクランナー等、JavaScript開発をするにあたって無数の辟易要因がありましたが、一通り落ち着いたように思います。改めて整理してみても__不揃いな実行環境__、モジュールシステムの乱立とバンドリング問題、__フロントエンドUIの高度化__ぐらいに的が絞られていて、しかもどれもデファクト候補の仕組みができつつあって、だいぶ見通しが良い感じです。この他の気になることを最後に「その他周辺のこと」としてまとめてみましたが、JSに限らずどの言語にも存在する一般的なWeb開発の課題しか残りませんでした。
これからのJavaScript開発が楽しくなりそうです。Webの未来は明るい。