Motomichi Works Blog

モトミチワークスブログです。その日学習したことについて書いている日記みたいなものです。

gulp+browserify+watchify+babelifyを導入してプロジェクトを作りなおしてみる

参考にさせて頂いたページ

ベースとして

Gulp + browserify + watchify + gulp-sass で自動高速コンパイル環境 – モンキーレンチ

watchify を試す – アカベコマイリ

babelについて

BabelでES2015の自動コンパイル環境を作る(Browserify / gulp / Grunt / webpack) | mae's blog

今日の環境

今回の意図するところ

browserifyとwatchifyを導入することでjsのビルドも速くしたいとか、自宅の環境で少し新しめの物に慣れてみようかと思った。
cssのビルドもcompassを使っていたんだけど、今後は自宅ではcompassに依存しない方向でやってみようと思う。
cssスプライトはgulp.spritesmithを使ってみる。

gulp-sassとかsassifyとか使ってみたいけど、ひとまず諦める。

そんな経緯もあって、ひとつのstyle.scssの中で全ての子_*.scssをimportするよりも、親となるscssをできるだけ小さいファイルサイズのscssに分割して、それが単品コンパイルされる度にcssをminifyする方がstyle.cssのビルドにかかる時間が安定して短いかと思ったのでその方向で進めてみる。

プロジェクトフォルダを作成して、npm init

project_0001を作成して、その中でnpm initした。

Macでgulp-sassがインストール失敗した

先日、Windows7でやったときは大丈夫だったけど、Mac OS X 10.7.5でインストールしようと思ったらエラーが出た。 しばらく調べたけどわからなかったので、gulp-sassはとりあえず諦めてgulp-ruby-sassを使用する事にした。

グローバルにgulpとbrowserifyとwatchifyとbabelをインストールする

参考ページにならって、

sudo npm install -g gulp browserify watchify babel

プロジェクトフォルダに色々インストール

一個ずつインストールしたり、まとめてやったり特に意味は無いんだけど、順番にインストールしてみた。

npm install --save-dev gulp
npm install --save-dev babel-preset-es2015
npm install --save-dev babelify
npm install --save-dev exorcist
npm install --save-dev browserify watchify
npm install --save-dev gulp-babel
npm install --save-dev gulp-sourcemaps
npm install --save-dev gulp-plumber
npm install --save-dev gulp-ruby-sass
npm install --save-dev gulp.spritesmith
npm install --save-dev gulp-uglify vinyl-source-stream vinyl-buffer
npm install --save-dev gulp-minify-css
npm install --save-dev gulp-rename
npm install --save-dev gulp-imagemin
npm install --save-dev merge-stream

.babelrcファイルの作成

touch .babelrc

記述内容は以下の通り

{
  "presets": ["es2015"]
}

package.json

最低限で一旦以下のような感じ。あとでまだ増えていくと思う。

{
  "name": "project_0001",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-preset-es2015": "^6.6.0",
    "babelify": "^7.2.0",
    "exorcist": "^0.4.0",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-plumber": "^1.1.0",
    "gulp-sourcemaps": "^1.6.0",
    "browserify": "^10.2.6",
    "gulp": "^3.9.0",
    "gulp-imagemin": "^2.3.0",
    "gulp-minify-css": "^1.2.0",
    "gulp-rename": "^1.2.2",
    "gulp-ruby-sass": "^1.0.5",
    "gulp-uglify": "^1.2.0",
    "gulp.spritesmith": "^3.8.2",
    "merge-stream": "^0.1.8",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0",
    "watchify": "^3.2.3"
  }
}

gulpfile.jsを書く

あとでもう少し直すけど一旦これで

/************************************************
 * モジュール読み込み
 ************************************************/
var gulp        = require('gulp');
var babel       = require('gulp-babel');
var plumber     = require('gulp-plumber');
var sourcemaps  = require('gulp-sourcemaps');
var rubysass    = require('gulp-ruby-sass');
var browserify  = require('browserify');
var watchify    = require('watchify');
var uglify      = require('gulp-uglify');
var source      = require('vinyl-source-stream');
var buffer      = require('vinyl-buffer');
var rename      = require('gulp-rename');
var minifyCss   = require('gulp-minify-css');
var spritesmith = require('gulp.spritesmith');
var merge       = require('merge-stream');



/************************************************
 * path設定
 ************************************************/
var SCSS_SRC_PATH        = './src/css_scss_img/scss/src_scss';
var CSS_SRC_PATH         = './src/css_scss_img/css/src_css';
var SPRITE_SRC_PATH      = './src/css_scss_img/img/src_img';
var JS_SRC_PATH          = './src/js';
var CSS_DEST_PATH        = './result/css';
var JS_DEST_PATH         = './result/js';
var SOURCEMAPS_DEST_PATH = './sourcemaps';


/************************************************
 * tasks
 ************************************************/

/**
 * JS_SRC_PATHに対するコンパイルを一回実行するタスク
 *
 * @return {Object} gulp ストリーム
 */
gulp.task('browserify',function(){
  return jscompile(false);//引数がfalseなので監視しない
});

/**
 * JS_SRC_PATHを監視して、JS_SRC_PATHに対するコンパイルを繰り返し実行するタスク
 *
 * @return {Object} gulp ストリーム
 */
gulp.task('watchify',function(){
  return jscompile(true);//引数がtrueなので監視する
});

// jscompile関数を定義
function jscompile(is_watch){
  // 変数bundlerにwatchify()またはbrowserify()を格納
  var bundler;
  if(is_watch){
    bundler = watchify(browserify(JS_SRC_PATH + '/main.js'));
  }else{
    bundler = browserify(JS_SRC_PATH + '/main.js');
  }

  //関数rebundleを定義
  function rebundle(){
    return bundler
      .bundle()
      .pipe(source('main.js'))
      .pipe(plumber())
      .pipe(buffer())
      .pipe(sourcemaps.init())
      .pipe(babel())
      .pipe(uglify())
      .pipe(sourcemaps.write(SOURCEMAPS_DEST_PATH))
      .pipe(gulp.dest(JS_DEST_PATH));
    }
    bundler.on('update',function(){
      rebundle();
    });
    bundler.on('log',function(message){
      console.log( message );
    });
    return rebundle();
  }

/**
 * SCSS_SRC_PATHとJS_SRC_PATHをトリガーとして監視するタスク
 * scssの監視は、gulp.watchで監視
 * jsの監視は、watchify+browserifyで監視
 * 
 * @return {Object} gulp ストリーム
 */
gulp.task('watch',['watchify'], function() {
  // gulp.watch('./src/css_scss_img/**/*.*',['lv2'])
  //   .on('change', function(event){
  //     eventObj = event;
  //   });
});

//深度2のタスク
gulp.task('lv2',function (){
  console.log('lv2実行中。');
  console.log('eventObj.typeは'+eventObj.type);//イベントタイプを出力(chenged,added,deletedなど)
  console.log('eventObj.pathは'+eventObj.path);//イベントパスを出力

  //src_preload_scss/*.scssが変更されたときに全てのscssをコンパイル
  REG_EXP_0001 = new RegExp("src_preload_scss", "i");
  if(eventObj.path.match(REG_EXP_0001)){
    console.log("scssを全てコンパイルします。");
    return rubysass('./src/css_scss_img/scss/src_scss/')
      .on('error', function (err) {
        console.error('Error!', err.message);
      })
      .pipe(gulp.dest(CSS_SRC_PATH + '/'));
  }

  //src_scss/*.scssが変更されたときに当該のファイルだけをコンパイル
  REG_EXP_0002 = new RegExp("src_scss", "i");
  if(eventObj.path.match(REG_EXP_0002)){
    console.log("scssを単品コンパイルします。");
    return rubysass(eventObj.path)
      .on('error', function (err) {
        console.error('Error!', err.message);
      })
      .pipe(gulp.dest(CSS_SRC_PATH + '/'));
  }

  //style.cssを生成
  REG_EXP_0003 = new RegExp("src_css", "i");
  if(eventObj.path.match(REG_EXP_0003)){
    console.log("style.cssを生成します。");
    return gulp.src(CSS_SRC_PATH + '/*.css')
      .pipe(minifyCss())
      .pipe(rename('style.css'))
      .pipe(gulp.dest('./result/css'));
  }

  //spritesmithを実行
  REG_EXP_0004 = new RegExp("src_img", "i");
  if(eventObj.path.match(REG_EXP_0004)){
    console.log("spritesmithを実行します。");
    var spriteData = gulp.src(SPRITE_SRC_PATH + '/*.png') //スプライトにする愉快な画像達
    .pipe(spritesmith({
      imgName: 'sprite.png', //スプライトの画像
      cssName: '_sprite.scss', //生成されるscss
      imgPath: '/img/sprite.png', //生成されるscssに記載されるパス
      cssFormat: 'scss', //フォーマット
      cssVarMap: function (sprite) {
        sprite.name = 'sprite-' + sprite.name; //VarMap(生成されるScssにいろいろな変数の一覧を生成)
      }
    }));

    var imgStream = spriteData.img
      // .pipe(imagemin())
      .pipe(gulp.dest('./result/img/')); //imgNameで指定したスプライト画像の保存先
    var cssStream = spriteData.css.pipe(gulp.dest('./src/css_scss_img/scss/src_preload_scss/')); //cssNameで指定したcssの保存
    return merge(imgStream, cssStream);
  }
});