如何根据文件更改修改grunt watch任务? [英] How to modify grunt watch tasks based on the file changed?

查看:195
本文介绍了如何根据文件更改修改grunt watch任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个node.js程序,该程序将观察充满大量(300小时)scSS项目的目录。 Grunt-watch(无论是通过节点模块运行还是独立运行,无论哪种方式运行)都将进行配置,以便无论何时更改scss文件,都将使用指南针进行编译,输出文件将移至单独的目录,例如:



./ 1234 / style.scss已更改>> grunt-watch运行grunt-compass >> /foo/bar/baz/1234/style.css更新



该文件所在的项目目录显然非常重要(如果grunt-compass将所有已编译的文件发送到同一个目录,它们将会混乱且不可用,无目的的)。我为了确保所有的文件都被路由到正确的位置,每次更新css文件时,我都会动态地改变grunt-compass设置。



示例gruntfile:

  module.exports = function(grunt){

grunt.initConfig({
pkg :grunt.file.readJSON('package.json'),
watch:{
files:'./*/*.scss',
tasks:['compass']
$,b $ b指南针:{
原产地:{
选项:{
//稍后要更改的后台设置
sassDir:'./',
cssDir:'./bar',
指定:'./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 +'可能有'+ action');
var siteDirectory = path.dirname(filepath);

//将sass目录更改为已更改文件的目录
var option ='compass.origin.options.sassDir';
var result = __dirname +'/'+ siteDirectory;
grunt.log.writeln(option +'changed to'+ result );
grunt.config(option,result);

//定制css输出目录,以便文件到达正确位置
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']);

});

};

然而这不起作用。如果以详细模式运行grunt watch,您会看到grunt在不同的进程中运行grunt.event.on函数和watch任务。 gruntfile的第二个解析会将我所有的event.on配置更改为上面的默认值,而指南针无法运行。



正如在event.on注释中所看到的,I试图添加一个grunt.task.run()以确保指南针在与event.on函数相同的进程中运行,这将保留我的配置更改。然而,该任务拒绝运行,可能是因为我做错了



不幸的是,grunt.event.on变量不会发送到定义的grunt-watch任务,否则我可以编写一个自定义函数指南针设置,然后在相同的过程中运行指南针。

我已经尝试实现这个没有咕噜声,使用手表功能构建到指南针,但是指南针只能存储一个每个项目的静态输出路径,并且只能同时观看一个项目。



我目前通过添加一个节点程序来解决这个问题,该程序将站点名称作为参数,通过使用fs运行来重写grunfile.js,然后通过exec函数运行'grunt watch'。然而,这有它自己的缺点(我无法查看grunt.log数据)并且非常复杂,所以我想改变它。



非常感谢对于任何见解都很有帮助。

解决方案

您需要指定

<在您的监视任务配置中使code> options:{nospawn:true}



使手表在相同的上下文中运行: / p>

  watch:{
files:'./*/*.scss',
tasks:['指南针'],
选项:{nospawn:true}
}

请参阅此部分的文档以获得更多相关信息。


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.

解决方案

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.

这篇关于如何根据文件更改修改grunt watch任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆