【问题标题】:How to modify grunt watch tasks based on the file changed?如何根据文件更改修改 grunt watch 任务?
【发布时间】:2013-07-29 15:17:45
【问题描述】:

我正在编写一个 node.js 程序,它将监视一个充满大量(300-ish)scss 项目的目录。 Grunt-watch (通过节点模块运行或单独运行,无论工作如何)将被配置,以便每当更改 scss 文件时,它将使用 compass 编译,输出文件移动到单独的目录,例如:

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

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

示例 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']);

  });

};

但是这不起作用。如果您在详细模式下运行“grunt watch”,您将看到 grunt 在单独的进程中运行 grunt.event.on 函数和 watch 任务。 gruntfile 的第二次解析将我的所有 event.on 配置更改恢复为上述默认值,并且 compass 无法运行。

正如在 event.on cmets 中看到的,我尝试添加一个 grunt.task.run() 以确保 compass 与 event.on 函数在同一进程中运行,这将保留我的配置更改。然而任务拒绝运行,可能是因为I'm doing it wrong

不幸的是,grunt.event.on 变量没有发送到定义的 grunt-watch 任务,否则我可以编写一个自定义函数来更改罗盘设置,然后在同一进程中运行罗盘。

我尝试在不使用 grunt 的情况下实现这一点,使用 compass 内置的 watch 功能,但是 compass 只能为每个项目存储一个静态输出路径,并且一次只能观看一个项目。

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

非常感谢您提供任何见解。

【问题讨论】:

  • 这不能回答你的问题,但为什么有一个 grunt-contrib-watch 指南针? Compass 已经自带compass watch
  • 您需要在监视任务配置中指定 options : { nospawn : true } 以使 watch 在相同的上下文中运行 (see this section in docs)。
  • @go-oleg 谢谢!这非常有效。我很惊讶我没有在文档中看到这一点,因为它直接指出 nospawn 解决了像我这样的问题。
  • @plelee grunt-contrib-watch 不是专门为指南针设计的,而是用于其他不带手表功能的自动化任务(如果您愿意,这将变得非常方便)编写您自己的自定义任务)。 compass watch 在很多情况下可能是完美的,但我在使用它来适应这个特定实例时遇到了麻烦,所以我改用grunt-contrib-watch
  • 我想我是想说grunt-contrib-compass,但是看起来你有一个非常具体的问题,compass watch 没有解决。

标签: node.js compass-sass gruntjs grunt-contrib-watch


【解决方案1】:

您需要指定

options : { nospawn : true }

在您的监视任务配置中让监视在相同的上下文中运行:

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

有关更多信息,请参阅文档的 this section

【讨论】:

  • 赞赏这个答案。已阅读文档,但不清楚“上下文”的含义以及它如何受到 nospawn 选项的影响。谢谢!
  • 要添加对此答案的更新,截至 2016 年 6 月,现在的选项是:spawn: false
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
相关资源
最近更新 更多