Search code examples
javascriptcoffeescriptgruntjslivereloadgrunt-contrib-watch

What files to watch with grunt-contrib-watch when wanting to reload Javascript files?


I have an app written in Coffeescript. My grunt.js file looks like this:

module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    clean: {
      test: {
        files: [{
          src: ['.tmp']
        }]
      }
    },
    coffee: {
      compileScripts: {
        expand: true,
        flatten: true,
        src: '*/*.coffee',
        dest: '.tmp/scripts',
        ext: '.js'
      },
    },
    jst: {
      compile: {
        files: {
          '.tmp/scripts/templates.js': ['scripts/**/*.ejs']
        }
      }
    },
    watch: {
      all: {
        options: {
          livereload: true,
          spawn: false
        },
        files: ['scripts/*.coffee', 'scripts/*.ejs', 'index.html'],
        tasks: ['compile'],
      }
    },
    connect: {
      server: {
        options: {
          port: 8000,
          hostname: 'localhost',
          open: true,
          livereload: true
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-coffee');
  grunt.loadNpmTasks('grunt-contrib-jst');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-connect');

  grunt.registerTask('compile', ['clean', 'coffee', 'jst']);
  grunt.registerTask('default', ['compile', 'connect', 'watch']);
}

After much tinkering, I finally got the 'watch' working where my JS files are live reloading, but I'm not clear on what goes in the 'files' section of the watch task? Did I do it right?

Do I have to watch the coffeescript files only? Or do I also have to watch index.html so that if one of the coffeescript files change, the index.html will refresh and reload the new JS? (All of my JS files are scripts in my index.html.)


Solution

  • The files property of the watch task contains a list of file patterns to watch and perform some action on when changed (most commonly run certain tasks).

    The tasks property contains the tasks you want to run when the corresponding files have been changed.

    Any target which has the livereload options configured on it will feed the files as they are changed to the live reload server. So if you have *.coffee files, they will be fed to the live reload server upon change. The live reload server only knows how to interpret js, css files so a .coffee file would refresh the entire page, instead of just the javascript.

    The tasks property is optional with the watch task so a common solution to better configuring the live reload is this:

    watch: {
      options: { spawn: false },
      all: {
        files: ['scripts/*.coffee', 'scripts/*.ejs'],
        tasks: ['compile'],
      },
      livereload: {
        options: { livereload: true },
        files: ['.tmp/**/*.{html,js,css}']
      }
    },
    

    So as your compile task runs it will trigger the watch:livereload target and live reload by feeding the correct files.

    Regarding the index.html, in your instance you probably don't need to watch that file within the watch:all target. As it doesn't have any tasks that do any building from it (at least from the config I see above).