2

我是 Grunt 的新手,从我到现在的理解,Grunt 有一个“监视”任务,它不断检查文件是否有修改,每次修改发生时,都会运行相应的任务。

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

似乎是很自然的要求,但我找不到这个。只是我,还是这真的是一个问题?

配置文件应如下所示:

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

Runninggrunt应该始终执行 tasks 'bar', 'foo',而 runninggrunt ifModified应该只在自上一次构建以来实际更改了某些文件时才执行任何任务。

4

3 回答 3

4

为此做了我自己的任务。事实证明并不难,这里是代码:

构建/任务/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
于 2013-06-18T20:13:47.983 回答
0

您可以从https://github.com/gruntjs/grunt/wiki/Creating-tasks创建一个有条件地运行其他任务的任务:

grunt.registerTask('foo', 'My "foo" task.', function() {
  // Enqueue "bar" and "baz" tasks, to run after "foo" finishes, in-order.
  grunt.task.run('bar', 'baz');
  // Or:
  grunt.task.run(['bar', 'baz']);
});
于 2013-06-18T11:04:06.470 回答
0

您需要的可能是 grunt-newer :

较新的任务将配置另一个任务以使用 src 文件运行,这些文件是 a) 比 dest 文件新或 b) 比上次成功运行(如果没有 dest 文件)新。有关示例和更多详细信息,请参见下文。

https://github.com/tschaub/grunt-newer

于 2014-10-22T09:43:09.290 回答