gulp-thumb

gulp使ってる人はほぼ間違いなくBrowsersyncを使ってるのではないでしょうか?すごく便利ですよね。gulpの導入記事でもよく紹介されています。

Browsersyncのいいところとしてファイルの内容を変更した時に自動でブラウザをリロードしてくれたり、手持ちのデバイスでの確認もできるということがよく書かれていると思います。

自動でリロードしてくれるのもいいですが、今回はブラウザをリロードするのではなく、変更したファイルのみを更新してくれるstreamオプションを使ってみたメモです。

もくじ
  1. インストール
  2. リロードする書き方
  3. stream
  4. 何がいいのか

インストール

今回はBrowsersyncとSassを使ってみます。

npm i gulp browser-sync gulp-sass -D

リロードする書き方

リロードする時はこんな感じで書くと思います。

var gulp = require('gulp');
var browserSync = require("browser-sync");
var sass = require('gulp-sass');
gulp.task('sass', function() {
  return gulp.src('./src/sass/!(_)*.{scss,sass}')
    .pipe(sass())
    .pipe(gulp.dest('./src/css/'));
});
gulp.task('server', function() {
  return browserSync.init({
    server: {
      baseDir: './src/'
    }
  })
})
gulp.task('bs-reload', function() {
  browserSync.reload();
})
gulp.task('watch',["server"], function () {
    gulp.watch('./src/sass/!(_)*.{scss,sass}', ['sass']);
    gulp.watch('./src/css/*.css', ['bs-reload']);
});

以下コマンドでファイル監視を始めます。

gulp watch

まず、Sassファイルが変更されればCSSへコンパイルし、次にCSSが変更されると「browserSync.reload()」でブラウザがリロードされます。

特に何てことないと思います。

stream

次にstreamを使った書き方です。ざっくり言うとreloadの代わりにstreamを使うだけですが、若干書き方変えてみました。

var gulp = require('gulp');
var browserSync = require("browser-sync");
var sass = require('gulp-sass');
gulp.task('sass', function() {
  return gulp.src('./src/sass/!(_)*.{scss,sass}')
    .pipe(sass())
    .pipe(gulp.dest('./src/css/'))
    .pipe(browserSync.stream());
});
gulp.task('server', function() {
  return browserSync.init({
    server: {
      baseDir: './src/'
    }
  })
})
gulp.task('watch',["server"], function () {
    gulp.watch('./src/sass/!(_)*.{scss,sass}', ['sass']);
    gulp.watch('./src/*.html').on('change', function() {
      browserSync.reload()
    });
});

sassタスクの最後にstreamをつけてみました。reloadの併用としてhtmlは変更されたらリロードするようにしています。PHPなどはストリームではうまく反映されないことがあるようなので。

コマンドは先ほどと同じで「gulp watch」です。

何がいいのか

上記2例の書き方で実際にSassの更新をしても、あまり違いが分からないかもしれないです。冒頭で書いたようにstreamは変更したファイルのみを更新してくれて、いちいちブラウザのリロードをしません。

具体例としては、親メニューにマウスオーバー時に子メニューが表示されるようなメニューを作っていたとします。

適当にこんな感じ

<ul>
  <li>リスト</li>
  <li>リスト
    <ul>
      <li>サブリスト</li>
      <li>サブリスト</li>
      <li>サブリスト</li>
    </ul>
  </li>
  <li>リスト</li>
</ul>

Sassでは子階層のulは非表示にしておき、liにマウスオーバーで表示という感じにしておきます。

li {
  position: relative;
  list-style: none;
  float: left;
  margin-right: 16px;
  &:hover {
    ul {
      display: block;
    }
  }
  ul {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    width: 200px;
    padding: 0;
  }
  li {
    float: none;
    margin: 0;
  }
}

このマウスオーバーしている時に表示される子メニューのスタイル調整をするとき、chromeであれば開発者ツールのhoverを選択した状態で検証したりすると思います。

ただ、このときBrowsersyncをリロードにしておくとブラウザがリロードされてしまうので、再び開発者ツールで選択しなおしになってしまいます。

しかし、ストリームにしておくとブラウザのリロードではなく、変更したファイルだけを更新するので、開発者ツールでhoverを選択したままコーディングを続けることができます。

これは一例ですが、他にもJSを使ってドロワーメニューや、モーダルを表示状態の時も同様に表示状態のままコーディングを進めることができます。

さいごに

Browsersync APIはこちらに書かれています。

Browsersync API

Browsersyncのちょっとしたネタでした。

一応参考までにこんな感じで作ってみてます。

web-starter-kit