Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
338 views
in Technique[技术] by (71.8m points)

node.js - How to modify grunt watch tasks based on the file changed?

I'm writing a node.js program that will watch a directory filled with a large (300-ish) amount of scss projects. Grunt-watch (run either through the node module or on its own, whatever works) will be configured so that whenever a scss file is changed, it will be compiled with compass, the output file moved to a separate directory, for example:

./1234/style.scss was changed >> grunt-watch runs grunt-compass >> /foo/bar/baz/1234/style.css updated

The project directory that the file was in is obviously very important (if grunt-compass sent all the compiled files to the same directory, they would be jumbled and unusable and the grunt automation would be purposeless). I order to make sure all files are routed to the correct place, I am dynamically changing the grunt-compass settings every time a css file is updated.

Sample gruntfile:

module.exports = function(grunt) {

grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    watch: {
      files: './*/*.scss',
      tasks: ['compass']
    },
    compass: {
      origin:{
        options: {
          //temportary settings to be changed later
          sassDir: './',
          cssDir: './bar',
          specify: './foo.scss'
        }
      }
    }
  });

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

  grunt.event.on('watch', function(action, filepath, target) {
    var path = require('path');
    grunt.log.writeln(target + ': ' + filepath + ' might have ' + action);
    var siteDirectory = path.dirname(filepath);

    //changes sass directory to that of the changed file
    var option = 'compass.origin.options.sassDir';
    var result = __dirname + '/' + siteDirectory;
    grunt.log.writeln(option + ' changed to ' + result);
    grunt.config(option, result);

    //customizes css output directory so that file goes to correct place
    option = 'compass.origin.options.cssDir';
    result = path.resolve(__dirname, '../', siteDirectory);
    grunt.log.writeln(option + ' changed to ' + result);
    grunt.config(option, result);

    //grunt.task.run(['compass']);

  });

};

However this doesn't work. If you run 'grunt watch' in verbose mode, you will see that grunt runs both the grunt.event.on function and the watch task in separate processes. The second parsing of the gruntfile reverts all my event.on config changes to the defaults above, and compass fails to run.

As seen in the event.on comments, I attempted to add a grunt.task.run() to make sure that compass was run in the same process as the event.on function, which would preserve my config changes. However the task refused to run, likely because I'm doing it wrong.

Unfortunately, the grunt.event.on variables are not sent to the defined grunt-watch task, otherwise I could write a custom function that would change the compass settings and then run compass in the same process.

I've tried implementing this without grunt, using the watch function build into compass, however compass can only store one static output path per project and can only watch one project at once.

I have currently gotten around this issue by adding a node program that takes the site name as a parameter, rewrites the grunfile.js by running using fs, and then running 'grunt watch' via an exec function. This however has it's own drawbacks (I can't view the grunt.log data) and is horribly convoluted, so I'd like to change it.

Thank you so much for any insight.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to specify

options : { nospawn : true }

in your watch task config to have the watch run in the same context:

watch: {
  files: './*/*.scss',
  tasks: ['compass'],
  options : { nospawn : true }
}

See this section of documentation for more info on this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...