0

由于Grunt 不支持仅重建已更改的内容,因此我想在其周围包装一个 Makefile,以仅计算“输入”文件集而不调用 grunt,除非它们中的任何一个自上次构建以来已更改。

你能告诉 grunt 以某种方式列出给定任务依赖于 stdout 的文件吗?

4

2 回答 2

5

您可以使用自定义任务来执行此操作,尽管它仍会被正常的 grunt 输出包装。

grunt.registerTask('src', function(){
  var taskConfig = grunt.config(this.args.join('.'));
  var expanded = grunt.task.normalizeMultiTaskFiles(taskConfig);
  expanded.forEach(function(files){
    files.src.forEach(function(file) {
      console.log(file);
    });
  });
});

列出所有文件的命令行语法,例如,名为“myFiles”的 jshint 子任务将是grunt src:jshint:myFiles

$ grunt src:jshint:myFiles
Running "src:jshint:myFiles" (src) task
file1.js
file2.js
dir/file3.js

Done, without errors.
于 2013-09-06T03:12:18.977 回答
0

根据jsoverson 的回答,我设法拼凑出一个概念证明,将依赖项跟踪推迟到 Gruntfile,因此我可以添加Makefile调用 grunt 位的规则来构建项目。该项目使用咖啡脚本(如果您想将其用于某些非咖啡项目,请使用http://js2coffee.org/Gruntfile.coffee转换为 js),所以在我添加

gruntGetPaths = (fn) -> ->
  taskConfig = grunt.config @args.join '.'
  grunt.task.normalizeMultiTaskFiles(taskConfig)
    .forEach fn ? (files) ->
      files.src.forEach (path) ->
        console.log path

grunt.registerTask 'src', gruntGetPaths
grunt.registerTask 'dst', gruntGetPaths (files) -> console.log files.dest

给我生成 grunt-junk-wrapped 文件列表的grunt src:...and规则。grunt dst:...

似乎垃圾可以保证被着色/添加一个尾随的空行(至少使用grunt v0.4.1/ grunt-cli v0.1.9),因此通过将它们的输出管道化来将其切断egrep -v '\e|^$'

在我的顶部附近,我Makefile为此添加了一些宏:

define GRUNT
    $(shell grunt --no-write $1 | egrep -v '\e|^$$')
endef
define SRC
    $(call GRUNT,src:$1)
endef
define DST
    $(call GRUNT,dst:$1)
endef

...然后是从以下方面借用知识的规则Gruntfile

$(call DST,stylus:compile): coffee $(call SRC,stylus:compile)
    grunt stylus

$(call DST,coffee:glob_to_multiple): coffee $(call SRC,coffee:glob_to_multiple)
    grunt coffee

$(call DST,uglify:my_target): coffee $(call SRC,uglify:my_target)
    grunt uglify

coffee:
    npm install 2>&1 | tee $@

...具有如下所示的相应设置:

  @initConfig
    pkg: grunt.file.readJSON "package.json"

    stylus:
      compile:
        options:
          paths: ["src/stylus/"]
          import: ["nib"]
        files:
          "stylesheets/foo.css": "src/stylus/foo.styl"
          "stylesheets/foo-dev.css": ["src/stylus/foo.styl", "src/stylus/foo-dev.styl"]

    coffee:
      glob_to_multiple:
        expand: true
        cwd: 'src/coffee/'
        src: ['*.coffee']
        dest: 'javascripts/'
        ext: '.js'

    uglify:
      my_target:
        files:
          "javascripts/foo.min.js": ["javascripts/foo.js"]

这有效,但速度很慢。给定一个需要 2.94 秒的裸grunt stylus运行,运行这些 make 规则来重新生成 css 需要另外 5.41 秒的纯开销,这有点可怕 - 如果我核对所有生成的文件并尝试重新生成 min.js,那里没有依赖解析,因为无法追溯 glob 规则以找到所有中间文件。

因此,虽然可以做到这一点,但它最终并没有解决“运行 grunt 缓慢而愚蠢,当没有更改源文件时”问题的解决方案,因为grunt stylus coffee uglify在这个项目中运行需要 3.25 秒来重现已经存在的内容,一个make仅仅解决依赖关系并且没有发现任何相关变化的裸运行需要五个。

如果grunt有自己的依赖管理知道什么时候可以立即退出当然很棒,就像我们祖父的工具一样。:-)

于 2013-09-22T00:28:47.283 回答