gruntjs - 如果某些文件发生更改,则有条件地在 grunt 中运行任务

标签 gruntjs

我是 Grunt 的新手,从目前为止我的理解来看,Grunt 有一个“watch”任务,它会不断检查文件是否有修改,每次修改发生时,都会运行相应的任务。

我正在寻找的是一种离散版本 - 一个任务,当且仅当自上次构建以来某些文件发生更改时,它才会运行其他任务。

这似乎是很自然的事情,但我找不到这个。是我一个人的问题,还是这确实是一个问题?

配置文件应如下所示:

grunt.initConfig({
  foo: {
    files: "foo/*"
    // some task
  },
  bar: {
    files: "bar/*"
    // some other task
  },
  ifModified: {
    foo: {
      files: "foo/*",
      tasks: ['foo']
    },
    bar: {
      files: 'bar/*',
      tasks: ['bar', 'foo']
    }
  }
});

grunt.registerTask('default', ['bar', 'foo']);

运行 grunt 应始终执行任务 'bar', 'foo',而运行 grunt ifModified 应仅在以下情况下执行任何任务:自上次构建以来,这些文件实际上已更改。

最佳答案

为此制定了我自己的任务。事实证明并不难,代码如下:

构建/tasks/if-modified.js:

var fs = require('fs');
var crypto = require('crypto');

module.exports = function (grunt) {

    grunt.registerMultiTask('if-modified', 'Conditionally running tasks if files are changed.', function () {

        var options = this.options({});

        grunt.verbose.writeflags(options, 'Options');

        var hashes = {};
        if (grunt.file.exists(options.hashFile)) {
            try {
                hashes = grunt.file.readJSON(options.hashFile);
            }
            catch (err) {
                grunt.log.warn(err);
            }
        }
        grunt.verbose.writeflags(hashes, 'Hashes');

        var md5 = crypto.createHash('md5');

        this.files.forEach(function (f) {
            f.src.forEach(function (filepath) {
                var stats = fs.statSync(filepath);
                md5.update(JSON.stringify({
                    filepath: filepath,
                    isFile: stats.isFile(),
                    size: stats.size,
                    ctime: stats.ctime,
                    mtime: stats.mtime
                }));
            });
        });

        var hash = md5.digest('hex');
        grunt.verbose.writeln('Hash: ' + hash);

        if (hash != hashes[this.target]) {
            grunt.log.writeln('Something changed, executing tasks: ' + JSON.stringify(options.tasks));

            grunt.task.run(options.tasks);

            hashes[this.target] = hash;
            grunt.file.write(options.hashFile, JSON.stringify(hashes));
        }
        else
            grunt.log.writeln('Nothing changed.');

    });
};

Gruntfile.js:

grunt.initConfig({
  foo: {
    src: ["foo/**/*"],
    dest: "foo-dest"
    // some task
  },
  bar: {
    src: ["bar/**/*", "foo-dest"]
    // some other task
  },
  'if-modified': {
    options: {
      hashFile: 'build/hashes.json'
    },
    foo: {
      src: ['foo/**/*', 'Gruntfile.js', 'package.json'],
      options: {tasks: ['foo']}
    },
    bar: {
      src: ['bar/**/*', "foo-dest", 'Gruntfile.js', 'package.json'],
      options: {tasks: ['bar']}
    }
  }
});

grunt.loadTasks('build/tasks'); // if-modified.js in this dir

grunt.registerTask('default', ['foo', 'bar']);

运行:

grunt if-modified

关于gruntjs - 如果某些文件发生更改,则有条件地在 grunt 中运行任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17167188/

相关文章:

css - 无法使用 grunt 编译 Bootstrap css

angularjs - 带有生成的名称调用的文件加速

javascript - 使用 Grunt 的多个文件夹和文件

less - 使用 Compass 内联 Bootstrap SASS 图像

javascript - Gruntfile 中止文件

html - 浏览器对@import的支持

gruntjs - 无法使用 npm 命令行安装 grunt

node.js - EJS 在 gruntfile 中转义

node.js - Browserify by Grunt.js watch

javascript - 常见任务在 GruntJS 中运行一次