2014/02/05更新

[grunt] ファイル保存したタイミングで、ブラウザを自動的にリロードして、確認作業をスピードアップさせよう

このエントリーをはてなブックマークに追加            

こんにちは、@yoheiMuneです。
HTMLやCSSやJSなどのフロントエンド開発を効率的に行いたい。そんな目標のもと、今回はgruntJSを使ってファイル保存したタイミングで、自動でブラウザリロードしてソースの変更内容を即座に確認する方法をブログに書きたいと思います!

画像

※2014/02/05更新
grunt-regardeではなくgrunt-contrib-watchでも出来るようになったので、記載を修正しました。



gruntJSのセットアップ

gruntJSは、 CSSプリプロセッサのコンパイル、JSファイルの結合などフロントエンドの開発で行うビルド作業を行うためのツールです。

まずはgruntjsが使えるようにセットアップを行います。 nodeとnpmを利用しますので、もしnodeやnpmをまだ導入していない方は、こちらからnodeやnpmをインストールしてください。
既にgruntjsを利用出来る環境の方は、gruntのインストール作業は不要です。

まずはgruntのコアとなる機能を導入します。
sudo npm install -g grunt-cli
これでgruntを動かすための最小の仕組みが入りました。
続いて、以下のコマンドを実行してgruntjsをインストールします。このコマンドは今回開発を行う際に利用するディレクトリで実行してください。
npm install grunt
これで現在の開発ディレクトリにgruntの導入が完了です。「node_modules」というディレクトリが作成され、その中にgruntのモジュールがインストールされます。


次にgruntを動かすためのJSファイルを作成します。 node_modulesディレクトリが存在するディレクトリに「Gruntfile.js」という名前のからのJSファイルを作成し、以下の内容を記述します。
module.exports = function(grunt) {
  grunt.initConfig({
    // ここにビルドタスクを記載していきます。
  });

  // 一連のタスクを登録します。
  grunt.registerTask('default', []);
};
上記のファイルを作成後に、以下のコマンドを実行して無事に処理が成功したら、gruntの導入は成功です。
grunt
gruntの処理が成功すると以下のようなメッセージが表示されます。
Done, without errors.
これでgruntjsの導入が完了です。



GruntJSでブラウザの自動リロードを行う

さてここからが本題です。gruntJSでブラウザの自動リロードを行う方法です。 ブラウザの自動リロードはいくつかの方法が存在しますが、今回はLiveReloadを利用します。

gruntJSで利用するモジュールのインストール

以下の内容を「package.json」として、Gruntfile.jsのあるディレクトリに保存します。
{
  "name": "grunt-livereload-sample",
  "version": "0.0.0",
  "description": "ERROR: No README.md file found!",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": "",
  "author": "",
  "license": "BSD",
  "devDependencies": {
    "grunt": "~0.4.2",
    "grunt-exec": "~0.4.3",
    "grunt-contrib-watch": "~0.5.3",
    "path": "~0.4.9",
    "grunt-contrib-connect": "~0.6.0",
    "grunt-open": "~0.2.3",
    "connect-livereload": "~0.3.2",
    "grunt-contrib-compass": "~0.7.1"
  }
}
そして以下のコマンドでモジュールをインストールします。
$ npm install
これで必要なモジュールは全部インストール出来ました。
なおインストールでエラーが起きる場合には、何度か試してみるか、sudoを付けて実行すると上手くいくことがあるかもしれません。


LiveReloadを使って、ファイル保存のたびにブラウザをリロードする

続いて、Gruntfile.jsで以下のように記述します。node.jsの記述も多少あるので、分かりづらい場合には丸っとコピーすれば動くはず:)
'use strict';

// liveReloadで使う変数とか処理を定義
var
    LIVE_RELOAD_PORT = 35729,
    lrSnippet = require('connect-livereload')({port: LIVE_RELOAD_PORT}),
    mountFolder = function (connect, dir) {
        return connect.static(require('path').resolve(dir));
    }

// Gruntの内容を定義
module.exports = function(grunt) {

    // 必要なモジュール読み込み
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-open');

    grunt.initConfig({
        watch: {
            options: {
                // このオプションを付けることで、liveReloadが出来ます
                livereload: LIVE_RELOAD_PORT
            },
            html: {
                files: ['./**/*.html'],
                tasks: ['']
            },
            css: {
                files: ['./**/*.css'],
                tasks: [''] // もしCompassなどのタスクがあればここに追加する。
            },
        },
        connect: {
            options: {
                port: 9000,
                hostname: '0.0.0.0'
            },
            livereload: {
                options: {
                    middleware: function (connect) {
                        return [
                            lrSnippet,
                            mountFolder(connect, './')
                        ];
                    }
                }
            }
        },
        open: {
            server: {
                url: 'http://localhost:<%=connect.options.port%>'
            }
        }
    });
    grunt.registerTask('default', ['connect:livereload', 'open', 'watch']);
};
上記の実装後に以下のコマンドを行うと、LiveRelaodが有効になります。
grunt
上記を実行すると「http://localhost:9000」のURLでブラウザに画面を表示することが出来ます(もしくは勝手にブラウザの画面が表示されます)。



LiveReloadを有効にするための設定

ファイルを保存したタイミングでブラウザを再読み込みするには、以下どちらかの設定が必要です。

[1]以下のJS読み込みをHTMLに記載する

以下のJSを読み込むようにHTMLに記載しておくと、liveReloadが有効になります。
<script src="http://localhost:35729/livereload.js"></script>
このJSは、gruntで「connect:livereload」で立ち上げているサーバーからJSをロードしています。 この読み込みを記載する場合には、LiveReloadを利用しない場面(本番など)では、読み込みが表示されないように制御する必要があります。


[2]ブラウザのエクステンションを使う

Chromeとかの場合、上記のような仕組みをエクステンションとして導入することが出来ます。以下からインストール出来ます。
画像
LveReload @Chromeウェブストア

インストールした後に、そのエクステンションのボタンをポチッと押すとLiveRelaodが有効になります。
これを使う注意点としては、gruntの再起動などをした場合に、LiveReload用のサーバーが一時的に停止してコネクションが切れてしまうという点です。 切れてしまったらもう一度、ポチッとボタンを押して有効化する必要があります。

個人的にはこの[2]の方法がオススメです。 Firefoxにもプラグインがあるみたいですね。



LiveReloadの使い方

それではLiveReloadを使った開発を少しやってみましょう。今回はHTMLとCSSが以下の構造で配置されていることとします。
  • + プロジェクトルート
    • - index.html
    • + cssディレクトリ
      • - styles.css
gruntを実行すると、connectタスクで指定した内容でサーバーが起動しますので、そのサーバーへブラウザでアクセスします。 上記の例では、以下のURLでアクセスできます(index.htmlが存在することを前提とします)。
http://localhost:9000/index.html
connectタスクで起動したサーバーにアクセスすると自動的にブラウザリロード用のJSがページに読み込まれます。



LiveReloadを実際に使ってみる

それではgruntタスクが動いている状態で、LiveRelaodの威力を体験してみましょう!
まずは最初以下のページが表示されているとします。
画像

まずはindex.htmlを編集してみます。
index.htmlの中で、文字列部分を修正してみます。
This is Sample HTML.AAAAA  <!-- AAAAAを追加 -->
ファイル保存をしたらすぐにブラウザは、以下の状態になりました。
画像
HTMLを変更したらすぐにブラウザに反映されるってすごいことですね。リロードのために「Command + R」とかしなくても良いなんて素敵です!
なぜindex.htmlを変更したらすぐにLiveReloadが実行されるかというと、Gruntfile.jsのregardeタスクで、「*.html」を監視対象としていて、HTMLファイルが変更されたらLivereloadが実行されるようにタスクが定義されているためです。

続いてCSSです。CSSファイルに以下の情報を追加してファイルを保存します。
body {
  background-color: red;
}
そうするとすぐに以下のような画面に変わります。
画像
キターー!!変更するたびにブラウザに反映されるじゃないですか。これでCSSを1行変えて確認するという細かいサイクルも苦になりません=*^-^*=
CSSもGruntfile.jsのregardeタスクで「css/*.css」として監視対象となっているため、cssディレクトリに存在する拡張子がcssのファイルが変更されるとlivereloadが実行されます。



最後に

フロントエンドでコーディングスピードをアップさせる6つの方法!でも熱弁してしまったのですが、「コードを書く -> 確認する」のサイクルを頻繁に行うことはほんとに大切。
そのために効率化したいという思いから、今回のブログも書きました。
今後の開発でもドンドンと使っていきたいと思います。

最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

[JS] Compass(Scss)のビルドが遅いので、マルチスレッドで高速でCompassビルドするgruntタスクを作ってみました
[grunt] gruntを使ってSFTPをファイル保存時に自動で行う
[grunt] ファイル保存したタイミングで、ブラウザを自動的にリロードして、確認作業をスピードアップさせよう
[grunt] Gruntfile.jsをチーム共有用と個人用にファイル分割して、gitやsvnのコンフリクトを減らす方法
[grunt] Compass(Sass)のマルチスレッドコンパイルができるgrunt-compass-multipleに、ファイルの個別指定オプションが追加
[gruntJS] gruntJSでタスクを実行する際に、引数で処理対象のファイルを変更する
[GruntJS] gruntからJenkinsのジョブを実行する
RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。