gulp+browserify+babel+haml+sass+S3 upload で静的サイトを作る


親戚に僕ができる範囲で良いのでタダで静的サイトを作れと強要されたので、90%勉強で今どき(ですよね…？)のフロントエンド開発とやらを体験してみようと上記構成でやってみた。

grunt?gulp?webpack????という状況で、噂で今ならgulpで良いんじゃね？と聞いたのでやってみたレベル…とフロント初心者。
変なことやってたり、古いやり方だったりすると思うのでマサカリお待ちしております。

## できること

- `gulp sass` で sass変換しつつ publish以下へ配置
- `gulp haml` で haml変換しつつ publish以下へ配置
- `gulp js` で browserify+es6変換しつつ publish以下へ配置
- `gulp image` で画像最適化しつつ publish以下へ配置
- `gulp build` で 上記変換系一括実行
- `gulp deploy` で buildした後にS3に自動アップロード
- `gulp develop` でブラウザを自動立ち上げ livereload状態になる。
	- plumber でコンパイルエラー時も止まらない
	- browserifyのエラー時も止まらない


## 参考サイト
[Gulp.js入門 - コーディングを10倍速くする環境を作る方法まとめ | 株式会社LIG](http://liginc.co.jp/web/tutorial/117900)
gulp公式のGetting Startedはインストールまでだったのでチュートリアル形式でわかりやすかった。

[JavaScript - React.js + Babel + Browserify + gulp の環境を作ってみた - Qiita](http://qiita.com/hkusu/items/e068bba0ae036b447754)
他はほぼ gulp-xxx を探せば簡単だったが browserifyだけはそのまま使えなかった。

[gulpfileをES6で書く - Qiita](http://qiita.com/kosuke_nishaya/items/cf7f8a2dbb8e47d064fd)

せっかくだからgulpfileもes6で書けるようにした。gulpfile自体大した量でも無く、変えるとgulpコマンドがもっさりになったのでやんなきゃ良かった気が…

[AWS - 【Gulp】gulp-s3-uploadプラグインで静的コンテンツをAmazon S3へ転送する - Qiita](http://qiita.com/kingpanda/items/0553cb6be9a0bbde7c27)

gulp-awspublish というプラグインでもS3アップロードできるみたいがこっちの方がただ S3にコピーするだけのシンプルっぽい感じだったので採用。

[browserifyでgulp-plumberが効かない時の対処方法 - Qiita](http://qiita.com/tanshio/items/b546b4b3eb2c648cb340)

browserifyのエラー時 gulp の watchが止まるので対策。

## ソース
gulpfileは以下。他はhaml/sass等のソースを配置するだけだし、package.jsonもライブラリ依存ぐらいなので省略。handle-errors.js は[browserifyでgulp-plumberが効かない時の対処方法 - Qiita](http://qiita.com/tanshio/items/b546b4b3eb2c648cb340) 内にあるものそのまま。


```gulpfile.babel.js
'use strict'

import gulp from 'gulp';
// file system node標準ぽい
import fs from 'fs'
import sass from "gulp-sass";
import haml from "gulp-haml";
// cssにvendor prefix をつける
import autoprefixer from "gulp-autoprefixer";
// css のスタイルガイドを作成、一人作業にはオーバースペック感
import frontnote from "gulp-frontnote";
// livereload 等
import browser from "browser-sync";
// 処理中にエラー出ても watcheを止めない
import plumber from "gulp-plumber";
import browserify from "browserify";
// browerify用babel
import babelify from "babelify";
// browserify がgulp.srcが使えないので生のstreamを取る用
import source from "vinyl-source-stream";
// 画像の最適化
import image from "gulp-image"

let config = JSON.parse(fs.readFileSync('/Users/yuichi/.aws/u1tnk_s3.json'));
// require('hoge')(args)が書けないようなので
import s3module from 'gulp-s3-upload'
let s3 = s3module(config)

// browserifyがplumberが効かないので対策用
import handleErrors from "./handle-errors.js";

gulp.task("sass", () => {
    gulp.src("sass/**/*.scss")
        .pipe(plumber())
        .pipe(frontnote({css: '../css/style.css'}))
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(gulp.dest("./publish/css"))
        .pipe(browser.reload({stream:true}));
});

gulp.task("js", () => {
    browserify({entries: ["./js/main.js"]})
        .transform(babelify)
        .bundle()
        .on('error', handleErrors)
        .pipe(source('bundle.js'))
        .pipe(gulp.dest("./publish/js"));
});

gulp.task("haml", () => {
    gulp.src("haml/**/*.haml")
        .pipe(plumber())
        .pipe(haml({pretty: true}))
        .pipe(gulp.dest("./publish/"));
});

gulp.task('image', () => {
    gulp.src('./images/**/*.+(jpg|jpeg|JPG|png|PNG|gif|GIF)')
        .pipe(plumber())
        .pipe(image({
            // ほぼsampleママ、無駄な設定もしてそうだが最適化はしている、要精査
            pngquant: true,
            optipng: false,
            zopflipng: true,
            advpng: true,
            jpegRecompress: false,
            jpegoptim: true,
            gifsicle: true,
            mozjpeg: true,
        }))
        .pipe(gulp.dest('./publish/images'));
});

gulp.task("reload", () =>{
    browser.reload()
});

gulp.task("server", () => {
    browser({
        server: {
            baseDir: "./publish/"
        }
    });
});

gulp.task("build", ['sass', 'js', 'image', 'haml'])

gulp.task("develop", ['server'], () => {
    gulp.watch("js/**/*.js", ["js", "reload"]);
    gulp.watch("sass/**/*.scss", ["sass"]);
    gulp.watch("haml/**/*.haml", ["haml", "reload"]);
    gulp.watch('./images/**/*.+(jpg|jpeg|JPG|png|PNG|gif|GIF)', ["image", "reload"]);
});

gulp.task("deploy", ['build'], function() {
  gulp.src(["./publish/**", "!./publish/**/.*"])
    .pipe(s3({
      Bucket: 'bucket-name',
      ACL: 'public-read',
    }))
  ;
});

```


## 感想など
- browser-syncのlivereloadが便利。haml/jsはreloadしてるが、cssの更新に至ってはブラウザのreloadすらやってない様子で、sassを編集した瞬間に変わるのは未来感ある。時代は変わった…
- livereloadが便利なのだが、haml編集してると真っ白になって手動reloadが必要になることがある。失敗する条件がまだわかっていない。
- 大抵は gulp-xxx を探せばできそうで安心感がある。
- JSなんてちょっと画像に動きをつけるぐらいでしか使わないので確実にオーバースペック。要件からするとwordpressとかの方が良かったと思う。
- 確かにRailsとの組み合わせは悩みそう。