【问题标题】:How can I use grunt-regarde with grunt-contrib-coffee to only compile changed .coffee files?如何使用 grunt-regarde 和 grunt-contrib-coffee 来仅编译更改的 .coffee 文件?
【发布时间】:2013-02-11 03:52:06
【问题描述】:

我的项目有 300 多个 CoffeeScript 文件,因此重新编译所有内容需要几秒钟的时间。我只想重新编译更改后的 CoffeeScript 文件。

这是我迄今为止最接近的,但“frontend-sr​​c/coffeescript”文件夹结构正在从 src 目录复制到 dest 目录。

coffee: {
  changed: {
    expand: true,
    cwd: './',
    src: ['<%= grunt.regarde.changed %>'],
    dest: 'public/js/',
    ext: '.js'
  }
},
regarde: {
  coffee: {
    files: 'frontend-src/coffeescript/**/*.coffee',
    tasks: ['coffee:changed', 'livereload']
  }
}

这就是 Grunt 0.4.0 的全部内容。任何帮助将不胜感激!

【问题讨论】:

    标签: coffeescript gruntjs


    【解决方案1】:

    grunt.regarde.changed 数组是否正确?

    应该src: ['&lt;%= grunt.regarde.changed %&gt;']

    成为src: '&lt;%= grunt.regarde.changed %&gt;'

    我查看了 grunt-contrib-coffee 的源代码一秒钟,看看它是否无法正确处理您提供的任何内容。看起来你给它的字符串化数组很可能没有被抓住和处理。

    我认为你不小心传递的可能是:src: [ '[path1, path2, path3, etc]' ]

    如果我离基地很远,请发表评论,我会删除这个答案。

    【讨论】:

    • src: '&lt;%= grunt.regarde.changed %&gt;' 为我工作(需要用字符串包裹)。
    • 谢谢,我在上面改了。
    【解决方案2】:

    我也遇到了同样的问题。我使用regarde:file 事件解决了它。

    首先,我使用regarde:file 事件来监听更改的文件。这将为两个任务提供配置:clean:coffee 如果源位置中的文件已被删除,coffee:refresh 如果文件已更改/添加。

    然后regarde 任务将触发它的任务,这将启动refresh:coffee(不要误认为coffee:refresh)。此任务将检查是否为clean:coffee 和/或coffee:refresh 添加了配置,并在需要时运行这些任务(通过函数grunt.task.run)。如果还会重置标志,这将导致下一个收到的regarde:file 事件再次清理配置。

    深入解释:

    首先,regarde 配置:

     // watch for changed coffeescript files
     coffee: {
        files: 'path/to/coffee/**/*.coffee',
        tasks: ['refresh:coffee', 'livereload']
     },
    

    然后我侦听regarde:file 事件,并在其中更新其配置中的clean:coffeecoffee:refresh 文件列表。

    根据regarde:file 事件提供配置:

    grunt.event.on('regarde:file', function (status, target, filepath) {
       if (resetFlag) {
          // clean file list from previous cycle, so clean clean:coffee and coffee:refresh
          // file lists
          ...
    
          resetFlag = false;
       } 
       if (status === 'deleted') {
            if (filepath) {
                // calculate filepath's destination and  
                // add it to clean:coffee filelist
            }
        } else {
            if (!grunt.file.isDir(filepath)) {
                // add filepath to coffee:refresh filelist
            }
        }
    }
    

    通过grunt.config() 函数可以轻松更新配置。下面的代码 sn-ps 提供 coffee:refreshclean:coffee

    将配置添加到coffee:refresh:

    var config = grunt.config('coffee') || {};
    var value = config.refresh || {};
    value.files = value.files || [];
    ...
    var cwd = path.dirname(filepath),
        src = path.basename(filepath),
        dest = cwd.replace('path/to/source', 'path/to/dest');
        value.files.push({
           expand:true,
           src:src,
           dest:dest,
           cwd:cwd,
           ext:'.js'
        });
    grunt.config('coffee', config);
    

    将配置添加到clean:coffee:

        var cwd = path.dirname(filepath),
            src = path.basename(filepath),
            dest = cwd.replace('path/to/source', 'path/to/dest');
            value.src.push(path.join(dest, src.replace('coffee', 'js')));
        // clean only what has been removed
            config = grunt.config('clean') || {};
    
        config.coffee = value;
    
        grunt.config('clean', config);
    

    任务refresh:coffee被触发:

        grunt.registerMultiTask('refresh', 'refreshing the changed file(s)', function () {
            this.requires('regarde');
    
            var tasks = [];
            var clean = grunt.config('clean');
    
            // check if there is clean:refresh config available
            if (clean && clean[this.target]) {
                tasks.push('clean:' + this.target);
            }
            var config = grunt.config(this.target);
    
            // check if there is coffee:refresh config available
            if (config && config.refresh) {
                tasks.push(this.target + ':refresh');
            }
            // run the tasks
            grunt.task.run(tasks);
    
            // set the resetFlag back to true
            resetFlag = true;
        });
    

    【讨论】:

      【解决方案3】:

      我自己也遇到了这个问题,并且在这个问题上受到 cmets 的启发,我能够想出一个解决方案: https://github.com/gruntjs/grunt-contrib-watch/issues/14

      它实际上适用于 grunt-contrib-watch 插件,但它也应该适用于 grunt-regarde,因为它有类似的事件。

      这个想法是绑定一个回调 watch 事件,在该事件中,您将一个新任务添加到具有更改文件路径的 grunt 配置中,然后运行它。

      来自我的Gruntfile.coffee

      coffee:
          app:
              expand: true
              cwd: 'app/'
              src: ['*.coffee',"**/*.coffee"]
              dest: './public/temp'
              ext: '.js'
      watch: 
          coffee:
              files: ['app/**/*.coffee']
              tasks: ['livereload']
              options:
                  nospawn: true
      
      grunt.event.on 'watch', (action, filepath) ->       
          cwd = 'app/'
          filepath = filepath.replace(cwd,'')
          grunt.config.set('coffee',
              changed:
                  expand: true
                  cwd: cwd
                  src: filepath
                  dest: './public/temp'
                  ext: '.js'
          )
          grunt.task.run('coffee:changed')
      

      nospawn 对 watch 任务很重要,因此它在 livereload 任务之前运行新任务。我很确定默认情况下不会产生子进程。

      【讨论】:

        猜你喜欢
        • 2014-02-25
        • 2013-07-22
        • 2015-06-13
        • 1970-01-01
        • 1970-01-01
        • 2012-09-30
        • 2013-02-16
        • 2018-08-22
        • 2013-10-15
        相关资源
        最近更新 更多