npm + gulp + bower でビルド自動化
(追記) この記事は公開から時間が経っており、内容が古くなっています。2016年時点ではWebpackが圧倒的におすすめです。
JavaScriptやCSSのビルドを自動化することで、手作業による無駄な時間やミスを削減できます。また、誰でもビルドできるようになるため、リリースのボトルネックを解消できます。
改善したいこと
- JavaScriptフレームワークやCSSフレームワークの依存関係を自動的に管理したい。ダウンロードして配置を手作業でやりたくない。
- CoffeeScriptやLESSのコンパイルを自動的に実行したい。手順書を見ながらコマンドを叩くとかやりたくない。
- ダウンロードしたライブラリをリポジトリに入れたくない。
- 出荷対象のリソースを明確にしたい。ゴミファイルをリリースしたくない。
どうやって実現する?
- bowerでライブラリの依存関係を管理する。
- gulpでビルドを自動化する。
- ライブラリのフォルダは .gitignore で除外する。
- ビルド時に別のフォルダにリソースを出力する。
- npmでビルドに必要なツール(bowerやgulp)の依存関係を管理する。
具体的な方法を説明します。
下記を前提とします。
- node.js がインストールされていること
- npm が使えること
新しいフォルダを作って git init
します。.gitignore に下記を入れておきます。
/build/ /bower_components/ /node_modules/
package.json を生成します。
npm init
最小限の package.json を自分で書いても構いません。
{ "name": "example", "description": "an example with npm, gulp and bower", "dependencies": {}, "devDependencies": {} }
bower でライブラリの依存関係を管理
bower をインストールします。
npm install -g bower
bower でライブラリを追加してみましょう。
bower init bower install angular --save
上記を実行すると bower_components/angular/ に AngularJS が格納されます。さらに bower.json に依存関係が保存されます。
ついでに Bootstrap も入れておきましょう。
bower install bootstrap --save
gulp でビルドを自動化
gulp はローカルにインストールする必要があります。ただし、ローカルだけでは node_modules/gulp/bin/gulp.js を実行する必要があるためグローバルにも入れておきます*1。
npm install -g gulp npm install gulp
gulp のスクリプトはJavaScriptでもCoffeeScriptでも書けますが、今回はCoffeeScriptを使いたいのでインストールしておきます。
npm install coffee-script --save-dev
gulpfile.js に下記を書いておくことで、スクリプト本体をCoffeeScriptで書けるようになります。
require('coffee-script/register'); require('./gulpfile.coffee');
gulpfile.coffee にタスクを書きます。
(2014/11/4) 思ったよりブクマが続いているので、スクリプトを差し替えました。gulp-rimrafやgulp-ngminはdeprecatedになっています。
# gulpfile.coffee: build script for front assets # # gulp - build assets # gulp watch - build assets continuously # gulp server - start a server with assets and mocked APIs sources = bower: 'bower.json' coffee: 'app/**/*.coffee' less: 'app/**/*.less' static: 'public/**/*' libs = js: [ 'angular/angular.min.js' 'angular-route/angular-route.min.js' ] css: ['bootstrap/dist/**/*.min.css'] static: ['bootstrap/dist/**/*'] bower = require 'bower' del = require 'del' gulp = require 'gulp' coffee = require 'gulp-coffee' concat = require 'gulp-concat' less = require 'gulp-less' ngAnnotate = require 'gulp-ng-annotate' nodemon = require 'gulp-nodemon' uglify = require 'gulp-uglify' gulp.task 'default', ['clean'], -> gulp.start 'compile:lib', 'compile:coffee', 'compile:less', 'compile:static' gulp.task 'clean', (cb) -> del 'target/webapp/', cb gulp.task 'watch', -> gulp.watch sources.bower, ['compile:lib'] gulp.watch sources.coffee, ['compile:coffee'] gulp.watch sources.less, ['compile:less'] gulp.watch sources.static, ['compile:static'] gulp.task 'compile:lib', -> bower.commands.install().on 'end', -> gulp.src libs.js.map (e) -> "bower_components/#{e}" .pipe concat 'lib.js' .pipe gulp.dest 'target/webapp/' gulp.src libs.css.map (e) -> "bower_components/#{e}" .pipe concat 'lib.css' .pipe gulp.dest 'target/webapp/' gulp.src libs.static.map (e) -> "bower_components/#{e}" .pipe gulp.dest 'target/webapp/' gulp.task 'compile:coffee', -> gulp.src sources.coffee .pipe coffee() .pipe ngAnnotate() .pipe uglify() .pipe concat 'app.js' .pipe gulp.dest 'target/webapp/' gulp.task 'compile:less', -> gulp.src sources.less .pipe less() .pipe concat 'app.css' .pipe gulp.dest 'target/webapp/' gulp.task 'compile:static', -> gulp.src sources.static .pipe gulp.dest 'target/webapp/' gulp.task 'server', ['compile:apimock'], -> gulp.start 'watch', 'watch:apimock' nodemon script: 'target/apimock.js' watch: ['target/apimock.js', 'target/webapp/'] env: port: 8888 webapp: "#{__dirname}/target/webapp/" gulp.task 'watch:apimock', -> gulp.watch 'apimock.coffee', ['compile:apimock'] gulp.task 'compile:apimock', -> gulp.src 'apimock.coffee' .pipe coffee() .pipe gulp.dest 'target/'
このスクリプトは下記を実行します。
- bowerの依存関係をインストールします。
- CoffeeScriptをコンパイルしてminifyします。minifyする時にAngularJSに必要な情報が失われないようにng-annotateを適用します。
- LESSをコンパイルします。
- すべてのリソースを build フォルダに保存します。
npm install gulp-coffee --save-dev npm install gulp-concat --save-dev npm install gulp-less --save-dev npm install gulp-ng-annotate --save-dev npm install gulp-nodemon --save-dev npm install gulp-uglify --save-dev
gulp コマンドでビルドを実行すると build フォルダにリソースが出力されます。
gulp
ファイルの変更を監視してビルドを実行するには watch タスクを実行します。
gulp watch
ローカルサーバでプレビュー
先ほどのタスクはファイルを生成するだけでしたが、gulpからローカルサーバを立ち上げてプレビューすることも可能です。expressで簡単なコードを書くことで、バックエンドAPIのスタブと組み合わせてプレビューできます。
以下の内容で apimock.coffee というスクリプトを配置します。
express = require 'express' app = express() app.use express.static process.env.webapp app.get '/api/v1/hoge', (req, res) -> res.set 'Content-Type', 'application/json' res.send JSON.stringify price: 100 app.post '/api/v1/hoge', (req, res) -> res.set 'Content-Type', 'application/json' res.send JSON.stringify price: 200 app.listen process.env.port
必要なパッケージをインストールしておきます。
npm install express --save-dev
serverタスクを実行することで、ローカルサーバがポート8888で起動します。
gulp server
別の環境で git clone した場合の対応
下記を実行するだけでビルドが完了します。
npm install gulp
ビルドも簡単になるし、リポジトリもすっきりするし、便利ですね。間違いがあったら指摘ください。
*1:正しいお作法を知っていたら教えてください