はじめに
今日はクライアントサイドWebアプリケーションの開発環境構築について書きたいと思います。
昨今、HTML, JS, CSSを駆使したWebアプリ開発の場においても、タスクランナーの導入は当たり前となってきました。
僕も日頃の業務ではフロントエンド用のタスクランナーとしてgulpを使っています。
gulpについては好きなところも嫌いなところもありますが、チームで仕事をする上では何らかのタスクランナーとビルドスクリプトの存在が欠かせないのは否定しません。
しかし、個人的に新しいフレームワークをちょっと勉強したいときにGruntやgulpのスクリプトをゼロから作成するのは、正直言って心が折れます。
YeomanやSlushJSでジェネレータを探すのも手ですが、自分の好みのフレームワーク、トランスパイラがセットで提供されないケースもしばしばです。
そうなると、結局自分でgulpfile.jsを読み解いた上で書き直す必要が出てきます。下手すると1からgulpfileを起こすよりも、他人が書いた物を理解する分だけ手間がかかることもあります。
そこで最近では、自分しか使わない勉強用のプロジェクトについては、gulpは使わずにCLIのみで済ませるようにしています。
ここでいうCLIとはbabel
や、tsc
, node-sass
といったコマンドを直接実行するという意味です。
勉強用プロジェクトでもっとも欲しくなるのは、gulp.watch('src/**/*.ts', ['compile:typescript']);
のような「ソースのwatch とファイル変換」ですが、調べてみると、大概のツールにはCLI自体に--watch
のようなオプションを持っていることが分かります。
今回はgulpを使わずにCLIだけで トランスパイル 〜 bundle 〜 LiveReloadを作る手順を紹介します。
コマンド名さえ覚えておけば、--help
を付けて叩けば細かいオプションはその場で確認できるため、慣れてしまえばgulpfile.jsを書くよりもスピーディに開発環境を構築できると思います。
TypeScript
まずはJavaScriptのトランスパイラ周りから。
TypeScript は静的な型付け機能をもったJavaScriptのSuper Setです。
npm install -g typescript
コマンドラインから色々引数を与えることもできますが、 CLI自体に設定ファイルの雛形生成機能があります。
tsc --init
を実行するとtsconfig.jsonが生成されるので、これを好みに書き換えるのが一番楽です。typoもしづらいですし。
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": true,
"outDir": "built",
"rootDir": "src",
"sourceMap": false
},
"exclude": [
"node_modules"
]
}
一度、tsconfig.jsonを作っておけば、 tsc -w
とするだけで、**/*.ts
を変更するたびに、built
の配下に.jsファイルを吐き出し続けてくれるようになります。
babel
babel もJavaScriptのトランスパイラとして人気のツールです。
npm -g install babel-cli
-w
または--watch
オプションでソースファイルの変更を検知して都度トランスパイルしてくれます。
babel -d dist -w src/**/*.js
ただ、babelの場合, 実際の変換処理を担っているbabel pluginをまとめたpresetが無いと殆ど何も出来ません。
例えば、ECMA 6thとReact JSXを使いたい場合、対応するpresetのinstallと--presets
の指定が必要となります。
npm install babel-preset-es2015 babel-preset-react --save-dev
babel -d dist -w src/**/*.js --presets es2015,react
presetはグローバルインストールしても意味がないので、install時に -g
は付けていません。
browserify
browserifyはcommonjsのrequire
を片っ端からかき集めて依存関係を解決した上で、単一の.js ファイルを作成するツールです。
以下のように、app.jsとそれを呼び出すbootstrap.jsが存在していたとしましょう。
console.log(require('./app'));
module.exports = 'Hello, world';
npm -g install browserify
browserify built/bootstrap.js -o bundle.js
出力されたbundle.jsをブラウザで読み込むと、コンソールに'Hello, world'
と出力されます。
browserify自体はwatchオプションを持っていませんが、代わりにwatchifyというツールが存在します。
npm -g install watchify
watchify built/bootstrap.js -o bundle.js -v
-v
(--verbose
)オプションが無いと、コンソールに一切の出力がなされず不安になってしまうので、付けておくことをオススメします。
browserify, watchifyともに -p babelify
のようにトランスパイラをpluginとして差し込むことも出来ます。
しかし、今回のエントリのようにCLIベースで組み立てるときは、トランスパイラはトランスパイラのCLI, browserify(watchify)は変換された.jsを元にbundle.jsを作るだけ、と分割して考えた方が楽と思っています。
中間ファイルの生成回数は増えるものの、各コマンドの叩き方がシンプルです。コマンドラインベースで物を考えるときは、1つのコマンドに作業を押し付けない方が後々で忘れにくいので。
Sass
ここまでJavaScriptの話でした。折角なので、CSSもCLIツールでwatchしてみます。
lib-sassのNode.jsラッパーである node-sassで.scssファイルを.cssへ変換しましょう。
npm -g install node-sass
node-sass sass/app.scss -w sass -r -o css
僕は普段、そんなに大量のmixinライブラリを使うようなことはしませんが、compassを少し使いたいぐらいのことであれば、npm install
と node-sassの--include-path
オプションで充分対応できます。
npm install compass-mixins
node-sass sass/app.scss -w sass -r -o css --include-path node_modules/compass-mixins/lib
@import 'compass';
// :
LiveReload
ここまでで、Alt-JS, Alt-CSSについて、ソースをwatchしながらトランスパイルしてbundle.jsやapp.cssを作ることが出来るようになりました。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My App</title>
<link rel="stylesheet" href="/css/app.css">
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
あとはこれらが変更された際に自動的にリロード、すなわちLiveReload機能を持たせたWebサーバを用意します。
LiveReload機能付のWebサーバといえば、browser-sync です。
npm install -g browser-sync
下記のように--files
オプションに変更検知対象のファイルを列挙していけば、これらが変更された際に自動的にReloadしてくれます。
browser-sync start --server --files index.html --files bundle.js --files css/app.css
ちなみに browser-sync init
とすると、bs-config.js
というファイル名で設定ファイルの雛形を吐き出してくれます。
このbs-config.jsをお好みで編集したのち、以下のようにCLIを実行するのも便利です。
browser-sync start --config bs-config.js
Put it all together
ここまでで、AltJS, AltCSSのトランスパイル, WebServerのLiveReloadをCLIで実現できるようになりました。
既にあなたのターミナルでは、watch系のプロセスが複数立ち上がっていることでしょう。
でも、毎回叩くの面倒ですよね?
折角なので、コマンド一発で起動できるようにしてみましょう。node-foreman というツールを利用します。foremanはプロセス管理を行うためのRuby製ツールで、node-foremanはこいつのnode.jsクローンです。
npm -g install foreman
続いてProcfile
という名前のファイルを作成し、これまでに叩いてきたCLIのwatch系コマンドをキー: コマンド
の形式で列挙していきます。
キーは分かりやすい名前であれば何でも構いません。
typescript: tsc -w
bundle: watchify built/bootstrap.js -o bundle.js -v
sass: node-sass sass/app.scss -w sass -r -o css --include-path node_modules/compass-mixins/lib
livereload: browser-sync start --server --files index.html --files bundle.js --files css/app.css
最後にnf start
コマンドを実行すれば、上記で列挙したプロセスが全て立ち上がってくれます。
nf start
おわりに
今回のエントリでは-w
(--watch
) オプションのあるCLIだけで開発環境を作ってみました。
TypeScript, Babel, Sassのコンパイル, browserifyによるbundle.jsの作成, Browser Syncでのライブリロード等を紹介しました。
CLIベースなので、シェルスクリプトと組み合わせれば自分用のジェネレータを作るのも簡単です。
実際に今回紹介した方法でangular2 betaのジェネレータを作ってみました。https://gist.github.com/Quramy/bc0a2ad00595e918b825
冒頭でも述べた通り、常にCLIが最良の選択肢と言いたい訳ではありませんが、「サクッと望みのフレームワークが動く」という目的を達成するだけであれば、CLIベースで組み立てる方が短時間で作成できます。
環境構築手段の1つとして、オプションに入れてみては如何でしょうか。