2013-02-25 6 views
11

В моем проекте более 300 файлов CoffeeScript, поэтому требуется перекомпилировать все несколько секунд. Я бы хотел только перекомпилировать измененные файлы CoffeeScript.Как использовать grunt-respecte с grunt-contrib-coffee для компиляции измененных файлов. Coffee?

Вот ближайший я зашел так далеко, но структура папки «frontend-src/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. Любая помощь будет принята с благодарностью!

ответ

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:coffee и coffee: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() функции. Ниже фрагментов кода для подачи coffee:refresh и clean: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; 
    }); 
0

grunt.regarde.changed - массив правильный?

Если src: ['<%= grunt.regarde.changed %>']

быть src: '<%= grunt.regarde.changed %>'

Я просмотрел источник рубаки-вно-кофейного на секунду, чтобы увидеть, если это может быть не правильно обработки, что вы даете его. Похоже, что строгий массив, который вы ему даете, не попадает и не сталкивается.

Я думаю, что вы передаете случайно может быть: src: [ '[path1, path2, path3, etc]' ]

Если я способ покинуть базу, оставьте комментарий, и я удалю этот ответ.

+1

'src: '<% = grunt.regarde.changed%>'' работал для меня (нужно было обернуть в строку). – Adam

+0

Спасибо, я изменил его выше. – nackjicholson

3

Я имел этот вопрос сам, и я был в состоянии придумать решение для его навеян комментариями по этому вопросу: https://github.com/gruntjs/grunt-contrib-watch/issues/14

Это на самом деле для хрюкать-вно-часовой плагин, но он должен также работают для ворчания, так как он имеет похожие события.

Идея заключается в привязке обратного вызова к событию 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 важно для выполнения этой задачи часов, поэтому он запускает новую задачу перед задачей LiveReload. Я почти уверен, что не по умолчанию порождает дочерние процессы.