【问题标题】:How do I list all files a given grunt task depends on for a Makefile?如何列出给定 grunt 任务依赖于 Makefile 的所有文件?
【发布时间】:2013-09-09 22:06:33
【问题描述】:

作为Grunt doesn't support only rebuilding what has changed,我想在它周围包装一个Makefile,只计算“输入”文件集而不调用grunt,除非它们中的任何一个自上次构建以来发生了变化。

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

【问题讨论】:

    标签: node.js makefile gruntjs


    【解决方案1】:

    您可以使用自定义任务执行此操作,尽管它仍会被正常的 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.
    

    【讨论】:

    • 谢谢 - 结合 grunt 自己的输出只会添加总是彩色和空行的假设,我设法拼凑了我的概念验证。我想我会放弃实验;它变慢了。
    【解决方案2】:

    基于jsoverson's answer,我设法拼凑出一个将依赖跟踪延迟到 Gruntfile 的概念验证,因此我可以添加调用 grunt 位来构建项目的Makefile 规则。这个项目使用咖啡脚本(如果你想在一些非咖啡项目中重用它,使用http://js2coffee.org/转换为js),所以在我的Gruntfile.coffee我添加了

    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 src:...grunt dst:... 规则,这些规则可以生成 grunt-junk-wrapped 文件列表。

    似乎保证垃圾会被着色/添加一个尾随空行(至少使用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 秒的纯开销,这有点可怕 - 如果我核对所有生成的文件并尝试重新生成最小值。 js,没有依赖解析,因为glob规则无法追溯找到所有中间文件。

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

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

    【讨论】:

      猜你喜欢
      • 2013-07-09
      • 2016-10-21
      • 2023-03-03
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 2015-03-16
      相关资源
      最近更新 更多