gulp + coffeescriptでお気楽フロント開発環境構築


普段家では開発しない私ですが, あまりにしょうもなくて会社では開発できない小規模アプリやプラグインを開発したいことがあります.

今回, そんな家でのお気楽開発環境としてCoffeeScript + gulpを採用したので, 概要や導入方法をメモりました.

CoffeeScriptとは?

CoffeeScriptは, AltJSと呼ばれるJavaScriptの高級代替言語(しょっぱいJavaScriptをもっといい感じにした言語)の1つです. AltJSにはTypeScript, Dart, JAXなど他にもいくつかありますが, 今回はお気楽開発ということで一番シンプルに記述できるものを選びました. ちなみに普段の業務では, お気楽とは程遠いGoogle Closureを利用しています.

AltJSに共通するのは, コンパイル後にJSを出力する点で, ブラウザは結局出力されたJSを利用します. ちなみにDartだけは, JS出力を残しつつも次世代のWebフロント言語としてJavaScriptを駆逐するという野心を持って開発されていたのですが, 2015年3月にそれを諦める宣言がなされました. 残念ですね.
http://news.dartlang.org/2015/03/dart-for-entire-web.html

gulpとは?

Node.jsベースのビルドツールです. CoffeeScriptやSassをコンパイルしたりlintしたり, jsをまとめて圧縮したりできます. Gruntと同じようなものですが, ビルドスクリプトが直観的で分かりやすく, フットワークが軽いので選びました.

開発環境構築

Node.jsのインストール

gulpを利用するためにまずNode.jsをインストールします.
https://nodejs.org/en/

プロジェクトの作成

下記のような構成で作成します.

  • build/js
    • app.min.js -> ビルド成果物
  • lib/js -> Jquery等の3rdParty置き場
  • src/js
    • app1.coffee -> アプリコード1
    • app2.coffee -> アプリコード2
  • package.json -> Node.js設定ファイル
  • gulpfile.coffee -> gulp設定ファイル
  • index.html -> テスト用HTMLファイル

gulp用ライブラリのインストール

# 基本セット
npm install --save-dev gulp gulp-coffee
# 圧縮用
npm install --save-dev gulp-concat gulp-uglify gulp-sourcemaps
# エラー処理
npm install --save-dev gulp-plumber gulp-notify
# その他ユーティリティー
npm install --save-dev gulp-util run-sequence

gulpのビルドスクリプトの記述

gulpfileはCoffeeScriptで記述します. CoffeeScriptの基本文法は下記が参考になります.
http://www.buildinsider.net/web/rubyonrails4/0901

gulpfile.coffee
# ライブラリのロード
gulp    = require "gulp"
coffee  = require "gulp-coffee"
concat  = require "gulp-concat"
notify  = require "gulp-notify"
util    = require "gulp-util"
plumber = require "gulp-plumber"
sourcemaps   = require "gulp-sourcemaps"
uglify  = require "gulp-uglify"
runSequence = require "run-sequence"

# エラー時にGUIでポップアップ表示.
errorProcess = 
  errorHandler: notify.onError "Error: <%= error.message %>"

# CoffeeScriptをJSに変換し, src/jsに出力
gulp.task "coffee", ->
  gulp.src "src/js/*.coffee" #対象ファイル
    .pipe plumber errorProcess #エラー処理
    .pipe coffee() #coffeeをjsにコンパイル
    .on "error", util.log 
    .pipe gulp.dest "src/js/" #出力先

# ビルド物生成
gulp.task "js.build", ->
  gulp.src [ "lib/js/*.js", "src/js/*.js" ]
    .pipe plumber errorProcess
    .pipe sourcemaps.init() # sourcemaps作成
    .pipe concat "app.min.js" # ファイルを結合 
    .pipe uglify() #圧縮            
    .pipe sourcemaps.write "./" #app.min.js.mapの書き出し
    .pipe gulp.dest "build/js/" #app.min.jsの書き出し

# CoffeeScriptのコンパイルからビルド物生成まで
gulp.task "build", -> runSequence "coffee", "js.build"

# CoffeeScriptファイルに変更があったら, jsを随時ビルド(結合圧縮まですると時間がかかるのでしない)
gulp.task "watch", ->
  gulp.watch "src/js/*.coffee", ["coffee"]

ビルドと監視

gulpタスク実行のため, package.jsonに下記プロパティを追加します.

package.json
{
# ...
  "scripts": {
    "build": "gulp build",
    "watch": "gulp watch"
  },
# ...
}
ビルドと監視
#ビルド
npm run build
#監視
npm run watch

gulpをglobal installして直接gulpを蹴る方法もありますが, 環境に依存してくるので上記のようにnpm経由で実行する方が良いです.