PHP と Grunt で ブラウザのアドオンを使わずに LiveReload する

PHP Advent Calendar 2013 in Adventar の13日目です。

前日は @Mankin_jp さんの PHP 〜5.5の入り口として〜 便利なパスワードハッシュ関数を使おう! でした。

ちなみにまだ 5.4 な人は password-compat を使うといいと思います。私はまだメインが 5.4 なので使ってます。


先日 Grunt + PHP ビルドインウェブサーバで LiveReload する方法を書きました。

この方法だとブラウザのアドオンが必要ですが・・・

なんということでしょう Internet Explorer のアドオンがありません。

とてもゆゆしきじたいなのでアドオンを使わずにどうにかできるようにします。

ブラウザのアドオンを使わずに LiveReload

Grunt のプラグインをいろいろ追加します。

$ npm install --save-dev grunt-contrib-connect
$ npm install --save-dev grunt-connect-proxy
$ npm install --save-dev grunt-contrib-watch
$ npm install --save-dev grunt-php

Gruntfile.js を次のように作成します。

Gruntfile.js

module.exports = function (grunt) {

    var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;

    grunt.initConfig({
        php: {
            options: {
                port: 5000,
                base: 'public/'
            },
            dist: {}
        },
        watch: {
            src: {
                options: {
                    livereload: true
                },
                tasks: [],
                files: [
                    'public/**/*.php',
                    'public/**/*.css',
                    'public/**/*.js'
                ]
            }
        },
        connect: {
            options: {
                port: 9000,
                base: 'public/',
                hostname: 'localhost',
                livereload: true,
                open: true,
                middleware: function (connect, options) {
                    return [
                        //connect.static(options.base),
                        proxySnippet
                    ];
                }
            },
            proxies: [
                {
                    context: '/',
                    host: 'localhost',
                    port: 5000,
                    https: false,
                    changeOrigin: false,
                    xforward: false
                }
            ]
        }
    });

    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-connect-proxy');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-php');

    grunt.registerTask('default', ['php:dist', 'configureProxies', 'connect', 'watch']);
};

適当にドキュメントルートのファイルを作ります。

public/index.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <link href="style.css" media="all" rel="stylesheet" type="text/css" />
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script src="script.js" type="text/javascript"></script>
</head>
<body>
<?php var_dump(date('Y/m/d H:i:s')) ?>
</body>
</html>

public/style.css

body {
    font-size: 200%;
}

public/script.js

$(function(){
    $('body').append($('<div></div>').text("I am script.js"));
})

Grunt を実行します。

$ grunt
Running "php:dist" (php) task
PHP 5.5.7 Development Server started at Fri Dec 13 10:18:19 2013
Listening on http://127.0.0.1:5000
Document root is d:\ng\work\example\php-grunt\public
Press Ctrl-C to quit.
[Fri Dec 13 10:18:20 2013] 127.0.0.1:50699 [200]: /

Running "configureProxies" task
Proxy created for: / to localhost:5000

Running "connect:proxies" (connect) task
Started connect web server on 127.0.0.1:9000.

Running "watch" task
Waiting...

恐らく FileFox か Google Chrome かそんな感じのブラウザが開くと思いますが、 速攻で閉じてスタートメニューから Internet Explorer を起動してアドレスバーに http://localhost:9000/ と打ち込みます。

それっぽい画面が表示されていると思います。さっそく index.php や style.css や script.js を編集してみてください。 Grunt が変更を検出して Internet Explorer がリロードされるはずです。

ざっくりとした説明

ざっくりと何が行われているのか説明すると・・・

  • grunt-phpPHP ビルドインウェブサーバを 5000 ポートで立てます
  • grunt-contrib-connect + grunt-connect-proxy でリバースプロキシを 9000 ポートで立てます
    • プロキシ先は grunt-phpPHP のビルドインウェブサーバです
    • リバースプロキシで HTML に LiveReload のための script タグを挿入します
      • ブラウザで LiveReload のアドオンを有効にするのと同じ効果です
  • grunt-contrib-watch でファイルを変更を監視して LiveReload をトリガします