Code Monkey home page Code Monkey logo

grunt-contrib-watch's Introduction

grunt-contrib-watch v1.1.0 Build Status: Linux Build Status: Windows

Run predefined tasks whenever watched file patterns are added, changed or deleted

Getting Started

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-contrib-watch --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-contrib-watch');

Watch task

Run this task with the grunt watch command.

Settings

There are a number of options available. Please review the minimatch options here. As well as some additional options as follows:

files

Type: String|Array

This defines what file patterns this task will watch. It can be a string or an array of files and/or minimatch patterns.

tasks

Type: String|Array

This defines which tasks to run when a watched file event occurs.

options.spawn

Type: Boolean
Default: true

Whether to spawn task runs in a child process. Setting this option to false speeds up the reaction time of the watch (usually 500ms faster for most) and allows subsequent task runs to share the same context. Not spawning task runs can make the watch more prone to failing so please use as needed.

Example:

watch: {
  scripts: {
    files: ['**/*.js'],
    tasks: ['jshint'],
    options: {
      spawn: false,
    },
  },
},

For backwards compatibility the option nospawn is still available and will do the opposite of spawn.

options.interrupt

Type: Boolean
Default: false

As files are modified this watch task will spawn tasks in child processes. The default behavior will only spawn a new child process per target when the previous process has finished. Set the interrupt option to true to terminate the previous process and spawn a new one upon later changes.

Example:

watch: {
  scripts: {
    files: '**/*.js',
    tasks: ['jshint'],
    options: {
      interrupt: true,
    },
  },
},

options.debounceDelay

Type: Integer
Default: 500

How long to wait before emitting events in succession for the same filepath and status. For example if your Gruntfile.js file was changed, a changed event will only fire again after the given milliseconds.

Example:

watch: {
  scripts: {
    files: '**/*.js',
    tasks: ['jshint'],
    options: {
      debounceDelay: 250,
    },
  },
},

options.interval

Type: Integer
Default: 100

The interval is passed to fs.watchFile. Since interval is only used by fs.watchFile and this watcher also uses fs.watch; it is recommended to ignore this option. Default is 100ms.

options.event

Type: String|Array
Default: 'all'

Specify the type of watch events that triggers the specified task. This option can be one or many of: 'all', 'changed', 'added' and 'deleted'.

Example:

watch: {
  scripts: {
    files: '**/*.js',
    tasks: ['generateFileManifest'],
    options: {
      event: ['added', 'deleted'],
    },
  },
},

options.reload

Type: Boolean
Default: false

By default, if Gruntfile.js is being watched, then changes to it will trigger the watch task to restart, and reload the Gruntfile.js changes. When reload is set to true, changes to any of the watched files will trigger the watch task to restart. This is especially useful if your Gruntfile.js is dependent on other files.

watch: {
  configFiles: {
    files: [ 'Gruntfile.js', 'config/*.js' ],
    options: {
      reload: true
    }
  }
}

options.forever

Type: Boolean
Default: true

This is only a task level option and cannot be configured per target. By default the watch task will duck punch grunt.fatal and grunt.warn to try and prevent them from exiting the watch process. If you don't want grunt.fatal and grunt.warn to be overridden set the forever option to false.

options.dateFormat

Type: Function

This is only a task level option and cannot be configured per target. By default when the watch has finished running tasks it will display the message Completed in 1.301s at Thu Jul 18 2013 14:58:21 GMT-0700 (PDT) - Waiting.... You can override this message by supplying your own function:

watch: {
  options: {
    dateFormat: function(time) {
      grunt.log.writeln('The watch finished in ' + time + 'ms at' + (new Date()).toString());
      grunt.log.writeln('Waiting for more changes...');
    },
  },
  scripts: {
    files: '**/*.js',
    tasks: 'jshint',
  },
},

options.atBegin

Type: Boolean
Default: false

This option will trigger the run of each specified task at startup of the watcher.

options.livereload

Type: Boolean|Number|Object
Default: false

Set to true or set livereload: 1337 to a port number to enable live reloading. Default and recommended port is 35729.

If enabled a live reload server will be started with the watch task per target. Then after the indicated tasks have run, the live reload server will be triggered with the modified files.

See also how to enable livereload on your HTML.

Example:

watch: {
  css: {
    files: '**/*.sass',
    tasks: ['sass'],
    options: {
      livereload: true,
    },
  },
},

Passing an object to livereload allows listening on a specific port and hostname/IP or over https connections (by specifying key and cert paths).

Example:

watch: {
  css: {
    files: '**/*.sass',
    tasks: ['sass'],
    options: {
      livereload: {
        host: 'localhost',
        port: 9000,
        key: grunt.file.read('path/to/ssl.key'),
        cert: grunt.file.read('path/to/ssl.crt')
        // you can pass in any other options you'd like to the https server, as listed here: http://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
      }
    },
  },
},

options.cwd

Type: String|Object
Default: process.cwd()

Ability to set the current working directory. Defaults to process.cwd(). Can either be a string to set the cwd to match files and spawn tasks or an object to set each independently. Such as:

options: {
  cwd: {
    files: 'match/files/from/here',
    spawn: 'but/spawn/files/from/here'
  }
}

To strip off a path before emitting events:

options: {
  cwd: {
    files: 'a/path',
    event: 'a/path'
  }
}

This will strip off a/path before emitting events. This option is useful for specifying the base directory to use with livereload.

options.livereloadOnError

Type: Boolean
Default: true

Option to prevent the livereload if the executed tasks encountered an error. If set to false, the livereload will only be triggered if all tasks completed successfully.

Examples

// Simple config to run jshint any time a file is added, changed or deleted
grunt.initConfig({
  watch: {
    files: ['**/*'],
    tasks: ['jshint'],
  },
});
// Advanced config. Run specific tasks when specific files are added, changed or deleted.
grunt.initConfig({
  watch: {
    gruntfile: {
      files: 'Gruntfile.js',
      tasks: ['jshint:gruntfile'],
    },
    src: {
      files: ['lib/*.js', 'css/**/*.scss', '!lib/dontwatch.js'],
      tasks: ['default'],
    },
    test: {
      files: '<%= jshint.test.src %>',
      tasks: ['jshint:test', 'qunit'],
    },
  },
});

Using the watch event

This task will emit a watch event when watched files are modified. This is useful if you would like a simple notification when files are edited or if you're using this task in tandem with another task. Here is a simple example using the watch event:

grunt.initConfig({
  watch: {
    scripts: {
      files: ['lib/*.js'],
    },
  },
});
grunt.event.on('watch', function(action, filepath, target) {
  grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
});

The watch event is not intended for replacing the standard Grunt API for configuring and running tasks. If you're trying to run tasks from within the watch event you're more than likely doing it wrong. Please read configuring tasks.

Compiling Files As Needed

A very common request is to only compile files as needed. Here is an example that will only lint changed files with the jshint task:

grunt.initConfig({
  watch: {
    scripts: {
      files: ['lib/*.js'],
      tasks: ['jshint'],
      options: {
        spawn: false,
      },
    },
  },
  jshint: {
    all: {
      src: ['lib/*.js'],
    },
  },
});

// On watch events configure jshint:all to only run on changed file
grunt.event.on('watch', function(action, filepath) {
  grunt.config('jshint.all.src', filepath);
});

If you need to dynamically modify your config, the spawn option must be disabled to keep the watch running under the same context.

If you save multiple files simultaneously you may opt for a more robust method:

var changedFiles = Object.create(null);
var onChange = grunt.util._.debounce(function() {
  grunt.config('jshint.all.src', Object.keys(changedFiles));
  changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
  changedFiles[filepath] = action;
  onChange();
});

Live Reloading

Live reloading is built into the watch task. Set the option livereload to true to enable on the default port 35729 or set to a custom port: livereload: 1337.

The simplest way to add live reloading to all your watch targets is by setting livereload to true at the task level. This will run a single live reload server and trigger the live reload for all your watch targets:

grunt.initConfig({
  watch: {
    options: {
      livereload: true,
    },
    css: {
      files: ['public/scss/*.scss'],
      tasks: ['compass'],
    },
  },
});

You can also configure live reload for individual watch targets or run multiple live reload servers. Just be sure if you're starting multiple servers they operate on different ports:

grunt.initConfig({
  watch: {
    css: {
      files: ['public/scss/*.scss'],
      tasks: ['compass'],
      options: {
        // Start a live reload server on the default port 35729
        livereload: true,
      },
    },
    another: {
      files: ['lib/*.js'],
      tasks: ['anothertask'],
      options: {
        // Start another live reload server on port 1337
        livereload: 1337,
      },
    },
    dont: {
      files: ['other/stuff/*'],
      tasks: ['dostuff'],
    },
  },
});
Enabling Live Reload in Your HTML

Once you've started a live reload server you'll be able to access the live reload script. To enable live reload on your page, add a script tag before your closing </body> tag pointing to the livereload.js script:

<script src="//localhost:35729/livereload.js"></script>

Feel free to add this script to your template situation and toggle with some sort of dev flag.

Using Live Reload with the Browser Extension

Instead of adding a script tag to your page, you can live reload your page by installing a browser extension. Please visit how do I install and use the browser extensions for help installing an extension for your browser.

Once installed please use the default live reload port 35729 and the browser extension will automatically reload your page without needing the <script> tag.

Using Connect Middleware

Since live reloading is used when developing, you may want to disable building for production (and are not using the browser extension). One method is to use Connect middleware to inject the script tag into your page. Try the connect-livereload middleware for injecting the live reload script into your page.

Rolling Your Own Live Reload

Live reloading is made easy by the library tiny-lr. It is encouraged to read the documentation for tiny-lr. If you would like to trigger the live reload server yourself, simply POST files to the URL: http://localhost:35729/changed. Or if you rather roll your own live reload implementation use the following example:

// Create a live reload server instance
var lrserver = require('tiny-lr')();

// Listen on port 35729
lrserver.listen(35729, function(err) { console.log('LR Server Started'); });

// Then later trigger files or POST to localhost:35729/changed
lrserver.changed({body:{files:['public/css/changed.css']}});
Live Reload with Preprocessors

Any time a watched file is edited with the livereload option enabled, the file will be sent to the live reload server. Some edited files you may desire to have sent to the live reload server, such as when preprocessing (sass, less, coffeescript, etc). As any file not recognized will reload the entire page as opposed to just the css or javascript.

The solution is to point a livereload watch target to your destination files:

grunt.initConfig({
  sass: {
    dev: {
      src: ['src/sass/*.sass'],
      dest: 'dest/css/index.css',
    },
  },
  watch: {
    sass: {
      // We watch and compile sass files as normal but don't live reload here
      files: ['src/sass/*.sass'],
      tasks: ['sass'],
    },
    livereload: {
      // Here we watch the files the sass task will compile to
      // These files are sent to the live reload server after sass compiles to them
      options: { livereload: true },
      files: ['dest/**/*'],
    },
  },
});

FAQs

How do I fix the error EMFILE: Too many opened files.?

This is because of your system's max opened file limit. For OSX the default is very low (256). Temporarily increase your limit with ulimit -n 10480, the number being the new max limit.

In some versions of OSX the above solution doesn't work. In that case try launchctl limit maxfiles 10480 10480 and restart your terminal. See here.

Can I use this with Grunt v0.3?

[email protected] is compatible with Grunt v0.3 but it is highly recommended to upgrade Grunt instead.

Why is the watch devouring all my memory/cpu?

Likely because of an enthusiastic pattern trying to watch thousands of files. Such as '**/*.js' but forgetting to exclude the node_modules folder with '!**/node_modules/**'. Try grouping your files within a subfolder or be more explicit with your file matching pattern.

Another reason if you're watching a large number of files could be the low default interval. Try increasing with options: { interval: 5007 }. Please see issues #35 and #145 for more information.

Why spawn as child processes as a default?

The goal of this watch task is as files are changed, run tasks as if they were triggered by the user himself or herself. Each time a user runs grunt a process is spawned and tasks are ran in succession. In an effort to keep the experience consistent and continually produce expected results, this watch task spawns tasks as child processes by default.

Sandboxing task runs also allows this watch task to run more stable over long periods of time. As well as more efficiently with more complex tasks and file structures.

Spawning does cause a performance hit (usually 500ms for most environments). It also cripples tasks that rely on the watch task to share the context with each subsequent run (i.e., reload tasks). If you would like a faster watch task or need to share the context please set the spawn option to false. Just be aware that with this option enabled, the watch task is more prone to failure.

How can I have the browser reload for files listed in a task?

Instead of restarting your server each time a static file is changed, start a static web server using (grunt-contrib-connect)[https://github.com/gruntjs/grunt-contrib-connect].

You'll have the connect web server on separate port ex: port 9000 from your main server. When the 'livereload' option is enabled for 'watch' tasks, it will handle triggering the live reload server for each tasks and when files are modified, which then server back to main server ex: 3000. The main server must include a script tag or a browser extension to the livereload server in order for the browser automatically.

Release History

  • 2018-05-12โ€ƒโ€ƒโ€ƒv1.1.0โ€ƒโ€ƒโ€ƒUpdate to [email protected], [email protected], [email protected]
  • 2018-04-20โ€ƒโ€ƒโ€ƒv1.0.1โ€ƒโ€ƒโ€ƒUpdate to [email protected], lodash@4
  • 2016-03-12โ€ƒโ€ƒโ€ƒv1.0.0โ€ƒโ€ƒโ€ƒUpdated tiny-lr, gaze, async and lodash dependencies. Fix endless loop issue with atBegin/nospawn. Expose hostname parameter of tiny-lr. Support cwd.event to emit events relative to path. Removed peerDependencies setting.
  • 2014-03-19โ€ƒโ€ƒโ€ƒv0.6.1โ€ƒโ€ƒโ€ƒFix for watch targets named "default".
  • 2014-03-11โ€ƒโ€ƒโ€ƒv0.6.0โ€ƒโ€ƒโ€ƒClear changed files after triggering live reload to ensure they're only triggered once. cwd option now accepts separate settings for files and spawn. Fix to make interrupt work more than once. Enable live reload over HTTPS. Print newline after initial 'Waiting...'. Remove deprecated grunt.util libs. Add reload option to specify files other than Gruntfile files to reload. Update to [email protected]. Use a fork of tiny-lr (which has quiter operation, support for HTTPS and Windows path fixes). Add livereloadOnError, which if set to false will not trigger live reload if there is an error.
  • 2013-08-25โ€ƒโ€ƒโ€ƒv0.5.3โ€ƒโ€ƒโ€ƒFixed for live reload missing files.
  • 2013-08-16โ€ƒโ€ƒโ€ƒv0.5.2โ€ƒโ€ƒโ€ƒFixed issue running tasks after gruntfile is reloaded. Ignores empty file paths.
  • 2013-07-20โ€ƒโ€ƒโ€ƒv0.5.1โ€ƒโ€ƒโ€ƒFixed issue with options resetting.
  • 2013-07-18โ€ƒโ€ƒโ€ƒv0.5.0โ€ƒโ€ƒโ€ƒAdded target name to watch event. Added atBegin option to run tasks when watcher starts. Changed nospawn option to spawn (nospawn still available for backwards compatibility). Moved libs/vars into top scope to prevent re-init. Bumped Gaze version to ~0.4. Re-grab task/target options upon each task run. Add dateFormat option to override the date/time output upon completion.
  • 2013-05-27โ€ƒโ€ƒโ€ƒv0.4.4โ€ƒโ€ƒโ€ƒRemove gracefully closing SIGINT. Not needed and causes problems for Windows. Ensure tasks are an array to not conflict with cliArgs.
  • 2013-05-11โ€ƒโ€ƒโ€ƒv0.4.3โ€ƒโ€ƒโ€ƒOnly group changed files per target to send correct files to live reload.
  • 2013-05-09โ€ƒโ€ƒโ€ƒv0.4.2โ€ƒโ€ƒโ€ƒFix for closing watchers.
  • 2013-05-09โ€ƒโ€ƒโ€ƒv0.4.1โ€ƒโ€ƒโ€ƒRemoved "beep" notification. Tasks now optional with livereload option. Reverted "run again" with interrupt off to fix infinite recursion issue. Watchers now close more properly on task run.
  • 2013-05-03โ€ƒโ€ƒโ€ƒv0.4.0โ€ƒโ€ƒโ€ƒOption livereload to start live reload servers. Will reload a Gruntfile before running tasks if Gruntfile is modified. Option event to only trigger watch on certain events. Refactor watch task into separate task runs per target. Option forever to override grunt.fatal/warn to help keeping the watch alive with nospawn enabled. Emit a beep upon complete. Logs all watched files with verbose flag set. If interrupt is off, will run the tasks once more if watch triggered during a previous task run. tasks property is optional for use with watch event. Watchers properly closed when exiting.
  • 2013-02-28โ€ƒโ€ƒโ€ƒv0.3.1โ€ƒโ€ƒโ€ƒFix for top level options.
  • 2013-02-27โ€ƒโ€ƒโ€ƒv0.3.0โ€ƒโ€ƒโ€ƒnospawn option added to run tasks without spawning as child processes. Watch emits 'watch' events upon files being triggered with grunt.event. Completion time in seconds and date/time shown after tasks ran. Negate file patterns fixed. Tasks debounced individually to handle simultaneous triggering for multiple targets. Errors handled better and viewable with --stack CLI option. Code complexity reduced making the watch task code easier to read.
  • 2013-02-15โ€ƒโ€ƒโ€ƒv0.2.0โ€ƒโ€ƒโ€ƒFirst official release for Grunt 0.4.0.
  • 2013-01-18โ€ƒโ€ƒโ€ƒv0.2.0rc7โ€ƒโ€ƒโ€ƒUpdating grunt/gruntplugin dependencies to rc6. Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
  • 2013-01-09โ€ƒโ€ƒโ€ƒv0.2.0rc5โ€ƒโ€ƒโ€ƒUpdating to work with grunt v0.4.0rc5.
  • 2012-12-15โ€ƒโ€ƒโ€ƒv0.2.0aโ€ƒโ€ƒโ€ƒConversion to grunt v0.4 conventions. Remove Node.js v0.6 and grunt v0.3 support. Allow watch task to be renamed. Use grunt.util.spawn "grunt" option. Updated to [email protected], forceWatchMethod option removed.
  • 2012-11-01โ€ƒโ€ƒโ€ƒv0.1.4โ€ƒโ€ƒโ€ƒPrevent watch from spawning duplicate watch tasks.
  • 2012-10-28โ€ƒโ€ƒโ€ƒv0.1.3โ€ƒโ€ƒโ€ƒBetter method to spawn the grunt bin. Bump gaze to v0.2.0. Better handles some events and new option forceWatchMethod. Only support Node.js >= v0.8.
  • 2012-10-17โ€ƒโ€ƒโ€ƒv0.1.2โ€ƒโ€ƒโ€ƒOnly spawn a process per task one at a time. Add interrupt option to cancel previous spawned process. Grunt v0.3 compatibility changes.
  • 2012-10-16โ€ƒโ€ƒโ€ƒv0.1.1โ€ƒโ€ƒโ€ƒFallback to global grunt bin if local doesn't exist. Fatal if bin cannot be found. Update to gaze 0.1.6.
  • 2012-10-08โ€ƒโ€ƒโ€ƒv0.1.0โ€ƒโ€ƒโ€ƒRelease watch task. Remove spawn from helper. Run on Grunt v0.4.

Task submitted by Kyle Robinson Young

This file was generated on Sat May 12 2018 21:15:02.

grunt-contrib-watch's People

Contributors

ansman avatar cepko33 avatar copasetickid avatar fundon avatar go-oleg avatar gonghao avatar ichernev avatar jakub-g avatar jasonsanjose avatar joeybaker avatar johnkpaul avatar jonmunson avatar jpillora avatar juriejan avatar leobalter avatar manuelcabral avatar marcelometal avatar mattcollier avatar mgol avatar mrjoelkemp avatar nackjicholson avatar ntwb avatar pdehaan avatar radkodinev avatar shama avatar sindresorhus avatar timothykang avatar trott avatar vladikoff avatar xhmikosr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grunt-contrib-watch's Issues

Watch stops before completing all tasks on Windows 7

Running on Windows 7 64 bit.

I have a project with lint and 42 mocha tests being run on watched file changes. This worked fine when i just run grunt. Producing output like this:

V:\GitHub\node-tls-tunnel>node_modules\.bin\grunt.cmd
Running "lint:node" (lint) task
Lint free.

Running "lint:nodeTest" (lint) task
Lint free.

Running "mochaTest:test" (mochaTest) task
 42  -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_,------,
 0   -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_|   /\_/\
 0   -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-^|__( ^ .^)
     -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-  ""  ""

  ? 42 tests complete (1.297 seconds)


Done, without errors.
V:\GitHub\node-tls-tunnel [master]>

However when run from watch though it does not run all the tests:

V:\GitHub\node-tls-tunnel>node_modules\.bin\grunt.cmd watch
Running "watch" task
Waiting...OK
>> File "grunt.js" changed.
Running "lint:node" (lint) task
Lint free.

Running "lint:nodeTest" (lint) task
Lint free.

Running "mochaTest:test" (mochaTest) task
 19  -_-_-_-_-_-_-_-_-_-_,------,
 0   -_-_-_-_-_-_-_-_-_-_|   /\_/\
 0   -_-_-_-_-_-_-_-_-_-^|__( ^ .^)
Waiting..._-_-_-_-_-_-_-  ""  ""

It seems to quit it before it completes (don't think it's a timeout though as you can see completing all the tests only takes 1.297 seconds)

This is my grunt file:

module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-contrib-watch');

  function getLintConfig() {
    return {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        es5: true,
        strict: false
      },
      globals: {
      }
    };
  }

  function getNodeLintConfig() {
    var config = getLintConfig();
    config.options.node = true;
    return config;
  }

  function getNodeTestLintConfig() {
    var config = getNodeLintConfig();
    config.globals.describe = false;
    config.globals.it = false;
    config.globals.before = false;
    config.globals.after = false;
    return config;
  }

  // Project configuration.
  grunt.initConfig({
    lint: {
      node: ['grunt.js', 'src/**/*.js'],
      nodeTest: ['test/src/**/*.js', 'test/integration/**/*.js']
    },
    jshint: {
      node: getNodeLintConfig(),
      nodeTest: getNodeTestLintConfig()
    },
    mochaTest: {
      test: ['test/src/**/*.js', 'test/integration/**/*.js'],
      doc: ['test/src/**/*.js']
    },
    mochaTestConfig: {
      test: {
        options: {
          reporter: 'nyan'        
        }
      },
      doc: {
        options: {
          reporter: 'doc'        
        }
      }
    },
    watch: {
      files: ['grunt.js', 'src/**/*.js', 'test/src/**/*.js', 'test/integration/**/*.js'],
      tasks: ['default']
    }
  });

  // Default task.
  grunt.registerTask('default', 'lint mochaTest:test');

  // Documentation task.
  grunt.registerTask('doc', 'mochaTest:doc');
};

I created grunt-mocha-test to work around issues in the builtin watch task that I hoped the grunt-contrib-watch task would address. So it's possibly a compatibility issue but i can't think of anything that would cause a problem. Also I think it worked ok on OSX (will check when i get home) and it worked fine on a Ubuntu VM. I haven't checked into your source yet but I remember testacular had some problems on windows using child_process.exec instead of child_process.spawn - could this be related?

How can grunt-contrib-livereload work with watch?

I am not sure if that's the right place to ask this...

I was trying to configure grunt livereload with watch but no reload was fired, instead i saw an error message:

>> Server is not started. Please do call livereload-start prior to any other task.

I had started the server as per the docs:

 grunt.registerTask('live', ['livereload-start', 'connect:livereload', 'watch']);

And this is my watch configuration:

    watch: {
      test: {
        options: {
          nospawn: true
        },
        files: ['test/**/*.js', 'src/**/*.js', 'lib/**/*.js', './*.js'],
        tasks: ['livereload', 'test:node']
      }
    }

I tried with nospawn set to false and true, nothing worked. Livereload only works with regarde.

/cc @sindresorhus @sleeper @tkellen

Fatal error: EACCES, readdir XXX

I've been getting strange EACCESS errors when trying to run grunt watch.

Fatal error: EACCES, readdir '/tmp/launchd-4643.AHyaSD'

Another example:

Fatal error: EACCES, readdir '/var/agentx'

Here is a full grunt watch --verbose:

Initializing
Command-line options: --verbose

Reading "Gruntfile.js" Gruntfile...OK

Registering Gruntfile tasks.
Reading package.json...OK
Parsing package.json...OK
Initializing config...OK

Registering "grunt-contrib-concat" local Npm module tasks.
Reading /Users/alejandro/Development/socure/node_modules/grunt-contrib-concat/package.json...OK
Parsing /Users/alejandro/Development/socure/node_modules/grunt-contrib-concat/package.json...OK
Loading "concat.js" tasks...OK
+ concat

Registering "grunt-contrib-uglify" local Npm module tasks.
Reading /Users/alejandro/Development/socure/node_modules/grunt-contrib-uglify/package.json...OK
Parsing /Users/alejandro/Development/socure/node_modules/grunt-contrib-uglify/package.json...OK
Loading "uglify.js" tasks...OK
+ uglify

Registering "grunt-contrib-jshint" local Npm module tasks.
Reading /Users/alejandro/Development/socure/node_modules/grunt-contrib-jshint/package.json...OK
Parsing /Users/alejandro/Development/socure/node_modules/grunt-contrib-jshint/package.json...OK
Loading "jshint.js" tasks...OK
+ jshint

Registering "grunt-contrib-watch" local Npm module tasks.
Reading /Users/alejandro/Development/socure/node_modules/grunt-contrib-watch/package.json...OK
Parsing /Users/alejandro/Development/socure/node_modules/grunt-contrib-watch/package.json...OK
Loading "watch.js" tasks...OK
+ watch

Registering "grunt-contrib-compass" local Npm module tasks.
Reading /Users/alejandro/Development/socure/node_modules/grunt-contrib-compass/package.json...OK
Parsing /Users/alejandro/Development/socure/node_modules/grunt-contrib-compass/package.json...OK
Loading "compass.js" tasks...OK
+ compass
Loading "Gruntfile.js" tasks...OK
+ default

Running tasks: watch

Running "watch" task
Verifying property watch exists in config...OK
Verifying properties watch.gruntfile.files, watch.gruntfile.tasks exist in config...OK
Verifying properties watch.lib_test.files, watch.lib_test.tasks exist in config...OK
Verifying properties watch.styles.files, watch.styles.tasks exist in config...OK
Waiting...Fatal error: EACCES, readdir '/var/agentx'

grunt --version output:

grunt-cli v0.1.6
grunt v0.4.0

This doesn't happens when running just grunt. Any clues about this? This started happening since upgrading to 0.4.

timers.js:103 TypeError: Bad argument

I'm running into a similar issue as #27 but I figure I should open a new issue. Running npm cache clean didn't work for me. The following are the versions of grunt and nodejs I'm using:

camilo@grinch-2 ~/Dropbox/Development/colombiajs/coljs.org (master) % grunt --version 
grunt v0.3.17
camilo@grinch-2 ~/Dropbox/Development/colombiajs/coljs.org (master) % node --version 
v0.8.12

This is the error I'm getting:

camilo@grinch-2 ~/Dropbox/Development/colombiajs/coljs.org (master) % grunt watch --force         
Running "watch" task
Waiting...
OK
>> File "content/about.md" changed.

timers.js:103
            if (!process.listeners('uncaughtException').length) throw e;
                                                                      ^
TypeError: Bad argument
    at ChildProcess.spawn (child_process.js:782:24)
    at exports.spawn (child_process.js:618:9)
    at Object.utils.spawn (/usr/local/lib/node_modules/grunt/lib/grunt/utils.js:90:15)
    at runTasks (/Users/camilo/Dropbox/Development/colombiajs/coljs.org/node_modules/grunt-contrib-watch/tasks/watch.js:85:33)
    at Object._.debounce.later [as _onTimeout] (/usr/local/lib/node_modules/grunt/node_modules/underscore/underscore.js:563:14)
    at Timer.list.ontimeout (timers.js:101:19)
camilo@grinch-2 ~/Dropbox/Development/colombiajs/coljs.org (master) %

this is my grunt file:

var fs = require('fs');

module.exports = function (grunt) {

  //options
  var concatOpts = {};
  var minifyOpts = {};
  var jadeFiles = {};
  var stylusFiles = {};
  var stylusPaths = [];

  //Builds options for frameworks used to avoid naming files individually
  var pages = fs.readdirSync('./lib');
  pages.forEach(function(page) {
    if (page == 'layout') return;

    concatOpts[page] = {
      src: ['<%= dirs.src %>' + page + '/*.js'],
      dest: '<%= dirs.dest %>/javascript/' + page + '.js'
    };

    minifyOpts[page] = {
      src: ['<%= dirs.dest %>/javascript/' + page + '.js'],
      dest: '<%= dirs.dest %>/javascript/' + page + '.min.js'
    };

    jadeFiles['<%= dirs.dest %>/' + page + '.html'] = ['<%= dirs.src %>/' + page + '/*.jade'];
    stylusFiles['<%= dirs.dest %>/styles/' + page + '.css' ] = '<%= dirs.src %>/' + page + '/*.styl';
    stylusPaths.push('<%= dirs.src %>/' + page);
  });

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

    meta: {
      banner: '/* <%= pkg.name %> - v<%= pkg.version %> - ' +
              '<%= grunt.template.today("yyyy-mm-dd") %> */'
    },

    dirs: {
      src: 'lib',
      dest: 'public'
    },

    lint: {
      all: ['grunt.js', '<%= dirs.src %>/**/*.js']
    },

    jshint: {
      options: {
        browser: true
      },
      globals: {
        jQuery: true
      }
    },

    /* Concat JS files per page*/
    concat: concatOpts,

    min: minifyOpts,

    jade: {
      compile: {
        options: {
          data: {
            debug: false,
            timestamp: '<%= grunt.template.today() %>',
            banner: '<!-- <%= pkg.name %> - v<%= pkg.version %> - ' +
                    '<%= grunt.template.today("yyyy-mm-dd") %> -->'
          },
          pretty: true
        },
        files: jadeFiles
      }
    },

    stylus: {
      compile: {
        options: {
          /* paths for @import() to look for */
          paths: stylusPaths,
          urlfunc: 'embedurl' // use embedurl('test.png') in our code to trigger Data URI embedding
          /*use: [
            require('blah') // use stylus plugin at compile time
          ]*/
        },
        files: stylusFiles
      }
    },

    watch: {
      files: ['<%= dirs.src %>/**/*', 'content/**/*'],
      task: 'default'
    },

    exec: {
      add: {
        command: 'git add public/*',
        stdout: true
      },

      commit: {
        command: 'git commit -m "Despliega รบltimos cambios" 2>&1',
        stdout: true
      },

      deploy: {
        command: 'git push origin HEAD:gh-pages 2>&1',
        stdout: true
      }
    },

    copy: {
      dist: {
        files: {
          '<%= dirs.dest %>/javascript/': 'third-party/**/*.js'
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jade');
  grunt.loadNpmTasks('grunt-contrib-stylus');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-exec');

  grunt.registerTask('deploy', 'lint jade stylus concat min copy exec');
  grunt.registerTask('default', 'lint jade stylus concat copy');
};

When watch globs return an empty fileset, a WARN is raised and the process exits.

I've got a project setup with file globs watching for patterns that may result in an empty fileset the first time a user runs grunt, in order to anticipate future additions to a directory which should result in my task list being run.

What's happening right now is that an empty fileset yields a WARN, and then the process exits. This seems counter to the design of grunt-contrib-watch. (The error message raised bubbles up from Fileset through Gaze into the console).

Here is a screenshot of the error manifesting with some console.logging to show what Gaze and the watch.js task are doing. I've also included my package.json dependencies for this project:

"dependencies": {
    "grunt": "0.4.0rc8",
    "grunt-contrib-clean": "0.4.0",
    "grunt-contrib-coffee": "0.4.0",
    "grunt-contrib-concat": "0.1.2",
    "grunt-contrib-handlebars": "0.5.4",
    "grunt-contrib-jshint": "0.1.1",
    "grunt-contrib-jst": "0.4.1",
    "grunt-contrib-less": "0.5.0",
    "grunt-contrib-mincss": "0.4.0rc7",
    "grunt-contrib-uglify": "0.1.1rc6",
    "grunt-contrib-watch": "0.2.0",
    "whet.extend": "0.9.9",
    "testem": "0.2.68",
    "commander": "1.1.1",
    "express": "3.1.0",
    "http-proxy": "0.8.7",
    "coffee-script": "1.4.0"
  },

Error in Action

Target not being hit

watch: {
  compass: {
    files: ['<%= application.src %>/styles/**/*.{scss,sass}'],
    tasks: ['compass']
  },
  css: {
    files: ['<%= application.development.src %>/styles/**/*.css'],
    tasks: ['reload']
  }
}

The result of this is:

$ grunt reload watch
Running "configure" task

Running "reload" task
Attempting reload at http://localhost:35729/triggerReload
Reload server running at http://localhost:35729

Running "watch" task
Waiting...Thu Jan 31 2013 17:17:08 GMT+0000 (GMT) Connection accepted.
OK
>> File "app/styles/main.scss" changed.
Running "configure" task

Running "compass:dev" (compass) task
overwrite temp/styles/main.css 

Running "compass:dist" (compass) task
unchanged app/styles/main.scss

Done, without errors.

Waiting...

The watch task doesn't seem to notice that a change has been made to the files monitored in the second task, css. These changes when they occur, however, will be the result from the first watch task, compass. I wonder if that could be the issue?

filechanges not noticed more than once per file

I'm having trouble using 'grunt watch' on *.hbs files in a folder. The *.hbs files are handlebars templates to be compiled with the ember_templates plugin, which by itself works as expected. The result should be a single javascript file with compiled templates.

The problem: when I save a hbs file it's the task runs, but it stops watching that specific file. Changes to other files still get noticed, but also just once for each file.
So each time this happens I have to stop 'grunt watch', run the compile command once, and restart 'grunt watch'.

I'm using:
OS X 10.8.2,
node v0.8.2,
[email protected],
[email protected].

Output of grunt watch when I save the file 'navigation.hbs' twice:

Running "watch" task
Waiting...OK
>> File "templates/navigation.hbs" deleted.
>> File "templates" deleted.
Running "ember_templates:all" (ember_templates) task
File "templates.compiled.js" created.

Done, without errors.

Update: Just updated to node 0.8.18. that didn't solve the problem either.

Unexpected reloading of Gruntfile

When a watcher fires, it seems to reload the Gruntfile, leading to unexpected results:

console.log('Gruntfile loaded');
module.exports = function(grunt) {
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    watch: {
      test: {
        files: 'whatever.txt',
        tasks: ['restart-thing']
      }
    }
  });

  (function() {
    var thingObj;

    grunt.registerTask('thing', function() {
      thingObj = new require('./thing.js').Thing();
    });

    grunt.registerTask('restart-thing', function() {
      thingObj.restart();
    });
  }());
};

When whatever.txt changes, the Gruntfile is reloaded, meaning restart-thing fails because thingObj is undefined.

Watch hogs CPU and Memory - clarification and how to avoid

You might want to mention this in the docs

After using grunt 0.4* for a while I noticed that one of my grunt processes hogged my CPU and memory to the border of insanity. I couldn't figure this one out and I only saw this error in a windows environment. See attached image below

node_cpu_mem_hog
node_cpu_mem_hog2

I realized, after a few more grey hairs, that in my grunt instance (gruntfile.js) I watched all **/*.js file in my project, including the folder node_modules (with over 5 000 files). After adding a negate on the node_modules folder, everyting worked out fine. See example below:

watch: {
  scripts : {
    files : [
      '**/*.js',
      '!node_modules/**/*.js'
    ],
    tasks: ['jshint', 'nodeunit'],
    options: {
      interrupt: true
    }
  }
}

Should this be in the docs? Or should grunt-contrib-watch have a default setting to NOT watch/ignore the node_modules folder? Or am I missing something?

grunt watch error

I'm running grunt watch with this setup:

 watch: {
      test: {
        files: ['app/js/**/*.js', 'test/**/*.js'],
        tasks: ['test']
      }
    }

When a file is changed this error is thrown:
Fatal error: Cannot call method 'on' of null ~/myapp $grunt-cli v0.1.5

The test task then proceeds to run and passes, then Grunt exits with "Done, without errors". I'm trying to track down which on method is blowing up.

node v 0.8.15
grunt-cli 0.1.5
grunt 0.4.0rc3

jsHint not working when watching

Here is my Gruntfile.js:

/*global module:false*/
module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({

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

    watch: {
      files: ['html/sass/*.scss', 'html/js/*.js'],
      tasks: ['default']
    },

    jshint: {
      all: ['html/js/*.js']
    },

    sass: {
        dist: {
          files: {
            'html/css/test.css': 'html/sass/test.scss'
          }
        }
      },
  });

  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Default task.
  grunt.registerTask('default', ['jshint']);

};

When I run grunt, jsHint gives me a few errors in the console. But when I try grunt watch, I get this:

Running "watch" task
Waiting...OK
>> File "html\js\za.js" changed.
Running "jshint:all" (jshint) task

Waiting...

grunt watch and async tasks

As requested on the issue found on the inbuilt watch task gruntjs/grunt#376 (comment)

@cowboy we have a less task that is async but it basically kills watch when an error is ran into. we will likely just add an if to call done() after error so it can continue through. however it brings up the question, in the normal flow of grunt (ie direct commands vs watch) do you really want it to continue through?

If i recall watch has logic to catch warnings that are fired. its also my belief that the fail.warn would auto stop the code during the normal flow so maybe its a non-issue? just looking for some guidance of how you think grunt should work with watch and async.

This was verified to still be an issue with version 0.1.2 (on node 8.11).

I've just re-reviewed the configuration options and modified them as outlined in the readme, removed the async task from the grunt build profile (which allows the watch task initialize as expected). This then leads to the watch task not actually triggering.

tty.isatty(1) and tty.isatty(2) are false, should be true

It seems that the environment tasks run in from watch is different than when run normally. This is causing mocha (and maybe other tasks) to behave differently. For example the output is in color normally, but not when run from watch.

grunt.registerMultiTask('tty', 'tty test', function() {
   var tty = require('tty');
   console.log('tty.isatty(1):', tty.isatty(1));
   console.log('tty.isatty(2):', tty.isatty(2));
});

normal grunt tty:

tty.isatty(1): true
tty.isatty(2): true

tty running from grunt-contrib-watch:

tty.isatty(1): false
tty.isatty(2): false

Mocha uses this to determine if color output should be used. This is very minor, but I'm guessing will bother people as they wonder why the output looks incorrect and what else is not working as expected.

Stops reacting to file changes after the first time

i'm on OSX 10.7.4 with node 0.8.8 using watch v0.1.4 and here's my grunt file

module.exports = function(grunt)
{
    grunt.loadNpmTasks('grunt-typescript');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-watch'); 

    grunt.initConfig({
        typescript : {
            base : {
                src     : [ 'src/**/*.ts' ],
                dest    : 'build',
                options : {
                    module    : 'commonjs', // or commonjs
                    target    : 'es5', // or es3
                    base_path : 'src/'
                }
            }
        },

        less : {
            development : {
                options : {
                    paths : [ 'src/less' ],
                    compress : false
                },
                files : {
                    'build/public/css/main.css' : 'src/less/main.less'
                }
            }
        },

        copy : {
            public : {
                files : {
                    'build/public/': 'src/public/**'
                }
            },
            views : {
                files : {
                    'build/views/': 'src/views/**'
                }
            }
        },

        watch : {
            typescript : {
                files : 'src/**/*.ts',
                tasks : [ 'typescript' ]
            },
            less : {
                files : 'src/less/**',
                tasks : [ 'less' ]
            },
            public : {
                files : 'src/public/**',
                tasks : [ 'copy:public' ]
            }
        }
    });

    grunt.registerTask('default', 'copy less typescript');
};

i run grunt watch and it works the first time i save the file and then no more... am i doing something wrong?

Using connect with watch to serve results in EADDRINUSE Edit

This issue was originally posted on the grunt-contrib-connect project, but I've since determined it's a watch bug.

I'm trying to set up a server using connect that reloads when a watched file changes. I've set this up as a serve task

grunt.registerTask("serve", ["connect", "watch"]);

The server starts fine the first time, but after a change is made, I get an EADDRINUSE error, and any subsequent watched changes aren't picked up. The server does continue to stay up, however.

Here is a pared down version of the Gruntfile I'm working with. https://gist.github.com/3989392

When I used a version of the server task from the current 0.3.x version of grunt, modified only to use grunt.util instead of grunt.utils, the bug is not present.

This specific bug first appears at commit 8f4bd99. Note that a different bug appears before that point, where the server bails out completely - but that's likely a different issue and not related to this issue.

Watch not acting on the correct files

I have set up the files I want JSHint to run on in jshint.files.src within the grunt config. The list looks like:

["foo/**/*.js", "!foo/bar/**", "foo/bar/baz/**/*.js"]

So, everything in foo/, unless it is in foo/bar/, unless it is in foo/bar/baz/. My jshint task correctly acts on the files specified.

For my watch task I have simply used:

"files": "<%= jshint.files.src %>"

The watcher correctly notices changes in foo/ but ignores an change within foo/bar/, even if it is in foo/bar/baz/.

For my full Gruntfile, see https://gist.github.com/wibblymat/5048924

Watch reports directories as being added that were not

Just put this in a comment on another issue but actually figured it should have it's own issue.

On a 64bit Ubuntu VM when i only save grunt.js I get the following output:

Waiting...OK
>> File "src" added.
>> File "grunt.js" changed.
Running "lint:node" (lint) task
Lint free.

Running "lint:nodeTest" (lint) task
Lint free.

Running "mochaTest:test" (mochaTest) task
 42  -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_,------,
 0   -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_|   /\_/\ 
 0   -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-^|__( ^ .^) 
     -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-  ""  "" 

  โœ” 42 tests complete (846 ms)


Done, without errors.

Waiting...

Note that the src directory already existed and was not added. Here is my grunt file:

module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-contrib-watch');

  function getLintConfig() {
    return {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        es5: true,
        strict: false
      },
      globals: {
      }
    };
  }

  function getNodeLintConfig() {
    var config = getLintConfig();
    config.options.node = true;
    return config;
  }

  function getNodeTestLintConfig() {
    var config = getNodeLintConfig();
    config.globals.describe = false;
    config.globals.it = false;
    config.globals.before = false;
    config.globals.after = false;
    return config;
  }

  // Project configuration.
  grunt.initConfig({
    lint: {
      node: ['grunt.js', 'src/**/*.js'],
      nodeTest: ['test/src/**/*.js', 'test/integration/**/*.js']
    },
    jshint: {
      node: getNodeLintConfig(),
      nodeTest: getNodeTestLintConfig()
    },
    mochaTest: {
      test: ['test/src/**/*.js', 'test/integration/**/*.js'],
      doc: ['test/src/**/*.js']
    },
    mochaTestConfig: {
      test: {
        options: {
          reporter: 'nyan'        
        }
      },
      doc: {
        options: {
          reporter: 'doc'        
        }
      }
    },
    watch: {
      files: ['grunt.js', 'src/**/*.js', 'test/src/**/*.js', 'test/integration/**/*.js'],
      tasks: ['default']
    }
  });

  // Default task.
  grunt.registerTask('default', 'lint mochaTest:test');

  // Documentation task.
  grunt.registerTask('doc', 'mochaTest:doc');
};

Options not fully implemented

As per grunt's guidelines this should work:

watch: {
 options: {
    nospawn: true
  },
  scripts: {
    files: ['**/*.js'],
    tasks: ['livereload'] 
  }
}

But this normal configuration returns this error:

>> Unable to process task.
Warning: Required config properties "watch.options.files", "watch.options.tasks" missing. Use --force to continue.

Add latest watch date

It could be great to have as information at the end of a watch the date of the compilation.

For example:

Compiled at 2013-01-20 08:45 -- Now waiting...

Yeah, sometimes I'm not behind my shell and don't see if it has compiled or not.

grunt.file.watchFiles

I've found my way from this question on SO here and was wondering what are the plans of supporting this option or is there another option discussed/being implemented that would allow for tasks to only run on the changed files and not on all watched files.

Update package.json for gaze within 0.1.4 Package

Hi,

If possible could you update to the package.json for the Gaze dependency (0.1.4) on npm as watch is not picking up when new files are created. After digging into the code it appears Gaze has now fixed the pattern matching when new files are added.

Jon

๐Ÿ‘

Missing abort/success message from min (UglifyJS) task?

Shame on me for using v0.3 still, but is there a reason for contrib-watch not displaying error message from UglifyJS task?

Even when UglifyJS-related task failed, watch plugin display the same OK message.

Waiting...OK
>> File "some.js" changed.
Running "min:app" (min) task

for other tasks such as LESS, there are clear success message such as:

File asset\css\client-0.0.5.css created.
File asset\css\ie-0.0.5.css created.

if I run the same UglifyJS task manually, it displays the error/success message just fine, but they do NOT appear when ran by watch.

Running "min:app" (min) task
Minifying with UglifyJS...ERROR
[L360:C46] Unexpected token name, expected punc (position: 8529)
<WARN> UglifyJS found errors. Use --force to continue. </WARN>

Aborted due to warnings.
Running "min:app" (min) task
File "asset/js/app-0.0.5.min.js" created.
Uncompressed size: 29600 bytes.
Compressed size: 3151 bytes gzipped (9660 bytes minified).

Done, without errors.

High CPU usage

When running grunt watch, the process sits around 70% cpu usage on my mac (10.8.2). Is this a known issue?

when multiple tasks watch the same path only one task runs

Lets say you have

watch:  {
            mocha: {
                files: ['lib/**/*.js'],
                tasks: ['mocha:all']
            },

            jshint: {
                files: ['lib/**/*.js'],
                tasks: ['jshint:all']
            }
}
grunt watch

When a change happens only the jshint task runs. It seems like the last task wins.

My expected behavior is that watch (or gaze) would notice the path already has a file watcher on it and just add another task on to run.

Fast changes get lost while tasks are completing

Watch tasks are triggered on an initial watch trigger but any changes that occur while the watch tasks are completing get ignored.

Expected :

  • Initial change immediately causes watch tasks to start
  • Any changes to files while those tasks are being completed trigger immediately after the initial run, and so on.

Following the documentation results in an error as too many files are loaded

Not sure what to make of this issue as I may not want to write such a rule in real code but while making a simple example to illustrate another issue I noticed the following problem.

The documentation shows the use of **/* as the pattern to watch so I tried it as follows:

module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.initConfig({
    lint: {
      files: ['grunt.js', 'src/**/*.js']
    },
    watch: {
      scripts: {
        files: ['**/*'],
        tasks: ['default']
      }
    }
  });

  grunt.registerTask('default', 'lint');
};

but this resulted in the following error when I tried to start the watch:

Waiting...^Clittle-toy:test pghalliday$ ./grunt.sh watch
Running "watch" task
Waiting...
events.js:68
        throw arguments[1]; // Unhandled 'error' event
                       ^
Error: EMFILE: Too many opened files.
    at Gaze._watchFile (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/lib/gaze.js:290:33)
    at Gaze._initWatched (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/lib/gaze.js:341:13)
    at Array.forEach (native)
    at Gaze._initWatched (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/lib/gaze.js:340:11)
    at async.forEachSeries.iterate (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/node_modules/async/lib/async.js:108:13)
    at async.forEachSeries.iterate (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/node_modules/async/lib/async.js:119:25)
    at Gaze._initWatched (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/lib/gaze.js:351:5)
    at async.forEachSeries.iterate (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/node_modules/async/lib/async.js:108:13)
    at async.forEachSeries.iterate (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/node_modules/async/lib/async.js:119:25)
    at Gaze._initWatched (/Users/pghalliday/Documents/test/node_modules/grunt-contrib-watch/node_modules/gaze/lib/gaze.js:351:5)
little-toy:test pghalliday$ 

I guess it tried to load everything in node_modules which only included grunt and grunt-contrib-watch. This could be a lot of files but it makes me wonder what the upper limit is and whether a normal project could reach it. Also maybe I want to detect changes in node_modules now i come to think of it.

Wrong added file events occurring

Using this config:

    watch: {
      gruntfile: {
        files: '<%= jshint.gruntfile.src %>',
        tasks: ['jshint:gruntfile']
      },
      js: {
        files: 'js/src/**/*',
        tasks: ['jam']
      },
      css: {
        files: 'css/src/**/*',
        tasks: ['compass']
      }
    }

Editing a dot file in the cwd will trigger: >> File "Gruntfile.js" added.
Could be related to #8.

Warning: Cannot read property 'message' of undefined Use --force to continue.

Having this trouble with the watch module, I'm thinking it has something to do with Grunt 0.4 incompatibilities/differences - see gruntjs/grunt-contrib-uglify#19 for same type of messages coming from uglify. Recommendation was to use a different release

"devDependencies": {
    "grunt": "~0.4.0",
    "grunt-contrib-jasmine": "latest",
    "grunt-contrib-jshint": "~0.1.1",
    "grunt-contrib-uglify": "~0.1.1",
    "grunt-recess": "~0.3.0",
    "grunt-contrib-watch": "~0.2.0"
  }
}

My tasks:

watch: {
            css: {
                files: 'static/css/*.css',
                tasks: ['recess:cssmin']
            }
}

Any ideas what might be causing this?

Watch stops working from time to time

After having run the task for about 10 minutes it stops to recognize file changes. Most of the time the last change on a file was printed in the console like this:

File "Gruntfile.js" deleted.

even it was a change in the file. After that any change in the file cant bring the watcher back to run the tasks.

Feature: Add Start Task Prior to Watching

In a complex build process, it can be very helpful to take advantage of per-file-set build tasks; for example, when a spec file changes, I only want to run the linter and the unit tests; but when a script file changes, I probably want to run most of my build, maybe excepting minification; etc.

To take advantage of this in a complex build process, I've taken to running grunt && grunt watch to run my default build process to get into a "start state" where I can safely run only the delta tasks - that is, only the tasks needed because a dependent file changed. An option to do this for me would be nice, e.g.:

watch: {
  options: {
    startWith: [ 'default' ]
  },
  filesetOne: {},
  filesetTwo: {},
  filesetThree: {},
}

If this is functionality you would consider including, I'd be happy to take a stab and submit a PR.

Add an option to exclude files

I use vim which creates files temporary files ending in ~ when I save. Sometimes (every few minutes but not reproducible on demand) these file are removed and it crashes watch

/usr/lib/node_modules/bbb/node_modules/grunt/lib/grunt/file.js:75
      throw grunt.task.taskError(e.message, e);
                       ^
TaskError: ENOENT, no such file or directory 'js/modules/participation/views.js~'
    at Task.taskError (/usr/lib/node_modules/bbb/node_modules/grunt/lib/util/task.js:59:17)
    at /usr/lib/node_modules/bbb/node_modules/grunt/lib/grunt/file.js:75:24
    at Array.filter (native)
    at Object.expandByType (/usr/lib/node_modules/bbb/node_modules/grunt/lib/grunt/file.js:69:40)
    at Timer.<anonymous> (/usr/lib/node_modules/bbb/node_modules/grunt/tasks/watch.js:158:44)
    at Timer.exports.setInterval.timer.ontimeout (timers.js:234:14)

Move the core of this task to a consumable lib?

Reference gruntjs/grunt#522. The grunt-reload task currently relies on a persistent variable set and then having the watch task call it to trigger a reload event. Since the watch task now spawns tasks as child processes this doesn't work anymore.

Should we consider moving the core of this watch task into a lib so other tasks can consume to be notified of watch events? Semi-related to #14. My grunt-hub task would also benefit from this as I duplicate a lot of the functionality there.

Here would be an example on how another task would implement:

var watch = require('grunt-contrib-watch');
watch.on('changed', function(filepath) {
  console.log(this.target); // target that triggered the event
  triggerReload(this.target);
});
// or on all events
watch.on('all', function(event, filepath) {});

follow up on https://github.com/gruntjs/grunt/issues/485

My grunt file is now :

module.exports = function(grunt) {
  grunt.initConfig({
      concat: {
          css: {
              src : [
                  'css/src/reset.css'
                , 'css/src/global.css'
                , 'css/src/formulaire.css'
                , 'css/src/aide.css'
                , 'css/src/ie/ie7.css'
                , 'css/src/ie/ie8.css'
                , 'css/src/ie/ie9.css'
             ]
            , dest: 'css/source.css'
          }
      }
    , watch: {
         css: {
              files: '<config:concat.css.src>'
            , tasks: 'concat:css'
         }}
  });

  grunt.registerTask('default', 'watch');

  grunt.loadNpmTasks('grunt-contrib-watch');
}

I got the following output

M:\qualiprest\site\node_modules>grunt.cmd watch
Loading "watch.js" tasks and helpers...ERROR
>> TypeError: Object #<Object> has no method 'exists'

Running "watch" task 
Waiting...OK
>> File "css/src/formulaire.css" renamed.

Running "concat:css" (concat) task 
File "css/source.css" created.

Running "watch" task
Waiting...
events.js:68
        throw arguments[1]; // Unhandled 'error' event
                   ^
Error: watch Unknown system errno 58
    at errnoException (fs.js:806:11)
    at FSEvent._handle.onchange (fs.js:824:26)

As you can see, it worked once, then crashed again

Not detecting added files on OSX and Windows 7

I just updated to grunt 0.3.17 and installed grunt-contrib-watch 0.1.2
I notice that now when I add files that match the files patterns the watch task no longer detects them

To verify this I created a really simple example. Using the following grunt.js if i add a new js file under the src directory lint is not run. However I know that it's working as saving grunt.js does result in lint being run and on all files including the new one. Watch only seems to watch new files if I restart it

module.exports = function(grunt) {

  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.initConfig({
    lint: {
      files: ['grunt.js', 'src/**/*.js']
    },
    watch: {
      scripts: {
        files: ['<config:lint.files>'],
        tasks: ['default']
      }
    }
  });

  grunt.registerTask('default', 'lint');
};

Not detecting added files on OSX

Grunt-contrib-watch isn't detecting files new file additions for me on osx. I assume this is related to issue #4 (the test provided in issue #4 confirms the problem). File changes and file deletions are handled correctly.

OSX: 10.8.2
node: 0.8.15
grunt: 0.3.17
grunt-contrib-watch: 0.1.4

Support Object Literals of Patterns

See gruntjs/grunt-contrib-sass#17.

The watch cannot currently read an object literal specified like this which is totally valid:

watch: {
  files: ['<%= sass.dev.files =>']
},
sass: {
  dev: {
    files: {
       'css/main.css': 'sass/main.scss'
    }
  }
}

But it should just read the values of the object literal for patterns.

compiling files as-needed

I know this is being discussed all over the place, and perhaps this idea has already been put forward, but I had a thought I wanted to put out there before I call it a night.

Here it is:

Could we write temporary gruntfiles for the spawned grunt processes that have configs that only hit the files which changed? I know there are a ton of edge cases here, but it seems like this might be possible for at least some use-cases. This will be really easy when we get to the stage where grunt tasks are "just a node module", but that is a long way off.

Timer.list exception when running task

Node: v0.8.16
grunt: v0.3.17
grunt-contrib-watch: v0.2.0a

When watch detects a file change, it throws the following error.

Running "watch" task
Waiting...OK
>> File "less/base/forms.less" changed.

timers.js:103
        if (!process.listeners('uncaughtException').length) throw e;
                                                                  ^
TypeError: Bad argument
    at ChildProcess.spawn (child_process.js:782:24)
    at exports.spawn (child_process.js:618:9)
    at Object.utils.spawn (/usr/local/lib/node_modules/grunt/lib/grunt/utils.js:90:15)
    at runTasks (/home/ahume/pasteup/node_modules/grunt-contrib-watch/tasks/watch.js:85:33)
    at Object._.debounce.later [as _onTimeout]     (/usr/local/lib/node_modules/grunt/node_modules/underscore/underscore.js:563:14)
    at Timer.list.ontimeout (timers.js:101:19)

grunt.fail will stop the watch task with the nospawn option

Opening this issue because I know somebody else will soon. :)

grunt.fail will stop the watch task if the nospawn option is enabled. In Grunt v0.3 we had a specialized warnAlternate so the watch task could re-run itself upon failure. Not in v0.4 but even then it didn't always catch all failures. This was one of the reasons the watch moved towards spawning as child processes.

A user can prevent this by setting --force but that isn't a good idea (and a really bad idea for the watch task to set for a user). Some APIs use --force to enable dangerous parts, such as --force will enable grunt.file.delete to remove files outside the cwd and potentially destroy a user's system.

So the question is, do we:

  • Ask for specialized handling of failures in grunt.fail?
  • If nospawn enabled, have the watch duck punch grunt.fail?
  • Listen to process events to try to rerun the watch task where necessary?
  • Just tell users to enable --force?
  • Some other solution?

onError actions for watch task

I'm using watch to constantly run my tests while I develop. I'd like to be able to specify tasks to run if the main tasks error out. With grunt-growl I could get desktop notifications any time jasmine fails.

I tried adding it myself so I could issue a pull request, but I was unsuccessful. It seemed I should be able to prefix nameArgs with the error commands in warnAlternate, but something about how the queue works I never seemed to get to those error commands. There's obviously more to it, but this is the direction I was headed.

grunt.fail.warnAlternate = function() {
  grunt.task.clearQueue({untilMarker: true}).run(/* 'grunt:build_failure' + */ nameArgs);
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.