Как я могу использовать grunt-contrib-watch и grunt-contrib-coffee для компиляции CoffeeScript только по мере необходимости?
Я бы хотел запустить кофейный линт и кофе, чтобы скомпилировать только один файл, который я сохраняю. В моем проекте сотни файлов CoffeeScript, и их компиляция занимает слишком много времени.
Здесь мой Gruntfile:
module.exports = (grunt) ->
grunt.initConfig
pkg: grunt.file.readJSON 'package.json'
coffee:
all:
expand: true
bare: true
cwd: 'src/coffeescript/'
src: '**/*.coffee'
dest: 'public/js/compiled'
ext: '.js'
coffeelint:
all: ['src/coffeescript/**/*.coffee']
watch:
coffeescript:
files: ['src/**/*.coffee']
tasks: ['coffeelint', 'coffee']
options:
spawn: false
grunt.event.on 'watch', (action, filepath) ->
grunt.config(['coffeelint', 'all'], filepath)
grunt.config(['coffee', 'all'], filepath)
grunt.loadNpmTasks 'grunt-coffeelint'
grunt.loadNpmTasks 'grunt-contrib-coffee'
grunt.loadNpmTasks 'grunt-contrib-watch'
grunt.registerTask 'default', ['coffeelint', 'coffee', 'watch']
Задача coffeelint выполняется успешно только в измененном файле.
Компиляция кофе не создает никаких JS файлов, хотя хрюкает, что она работает.
Здесь вывод после сохранения одного файла кофе:
OK
>> File "src/coffeescript/app.coffee" changed.
Running "coffeelint:all" (coffeelint) task
>> 1 file lint free.
Running "coffee:all" (coffee) task
Running "watch" task
Completed in 0.009s at Sat Feb 01 2014 13:10:07 GMT-0600 (CST) - Waiting...
Что здесь не так? Любая помощь будет принята с благодарностью!
Update:
Вот рабочий пример:
module.exports = (grunt) ->
fs = require 'fs'
isModified = (filepath) ->
now = new Date()
modified = fs.statSync(filepath).mtime
return (now - modified) < 10000
grunt.initConfig
coffee:
options:
sourceMap: true
bare: true
force: true # needs to be added to the plugin
all:
expand: true
cwd: 'src/coffeescript/'
src: '**/*.coffee'
dest: 'public/js/compiled'
ext: '.js'
modified:
expand: true
cwd: 'src/coffeescript/'
src: '**/*.coffee'
dest: 'public/js/compiled'
ext: '.js'
filter: isModified
coffeelint:
options:
force: true
all:
expand: true
cwd: 'src/coffeescript/'
src: '**/*.coffee'
modified:
expand: true
cwd: 'src/coffeescript/'
src: '**/*.coffee'
filter: isModified
watch:
coffeescript:
files: ['src/**/*.coffee']
tasks: ['coffeelint:modified', 'coffee:modified']
grunt.loadNpmTasks 'grunt-coffeelint'
grunt.loadNpmTasks 'grunt-contrib-coffee'
grunt.loadNpmTasks 'grunt-contrib-watch'
grunt.registerTask 'default', ['coffeelint:all', 'coffee:all', 'watch']
Ответы
Ответ 1
Попробуйте добавить что-то подобное к вашей задаче c
coffee:
all:
filter: (filepath) ->
fs = require('fs')
now = new Date()
modified = fs.statSync(filepath).mtime
return (now - modified) < 10000 # or another difference in millyseconds
Подробнее в документации
Ответ 2
Вы можете использовать grunt-newer только для компиляции файлов, когда источник является более новым, чем его скомпилированный вывод.
Установите его с помощью:
npm install grunt-newer --save-dev
Затем немного измените задачу coffeescript. Если вы перейдете в раздел "Построение объекта файлов динамически" в Grunt.js docs, вы увидите, что вам нужно провести соответствующую информацию указать местоположение и местоположение скомпилированного вывода в массиве files
для правильной работы задачи.
Дополнительные параметры, такие как bare: true
, могут быть указаны с помощью объекта options.
Итак, для вашей задачи coffee
сделайте следующее:
coffee:
all:
files: [{
expand: true
cwd: 'src/coffeescript/'
src: '**/*.coffee'
dest: 'public/js/compiled'
ext: '.js'
}]
options:
bare: true
spawn: false
то используйте новую задачу в вашей часовом задании так:
watch:
coffeescript:
files: ['src/**/*.coffee']
tasks: ['newer:coffeelint:all', 'newer:coffee:all']
options:
spawn: false
Затем Newer только компилирует файлы, которые являются более поздними, чем их скомпилированные версии.
Ответ 3
Здесь есть две проблемы.
Во-первых:
Grunt создает измененный путь к файлу как src/coffeescript/some_file.coffee
, но в вашей задаче coffee
вы определили cwd
как src/coffeescript
.
Итак, задача на кофе действительно ожидает только some_file.coffee
, но она получает src/coffeescript/some_file.coffee
, а затем расширяет ее до src/coffeescript/src/coffeescript/some_file.coffee
O_o
В вашей задаче coffeelint
нет cwd
, поэтому она успешно запускается с полным пути к файлу.
Соответственно отредактируйте путь к файлу или удалите cwd
из конфигурации кофе.
grunt.config(['coffee', 'all'], filepath.replace("src/coffeescript", ""))
Второе:
Этот малый, и может не потребоваться, но не забудьте также об этом.
grunt.event.on 'watch', (action, filepath) ->
grunt.config(['coffeelint', 'all'], filepath)
grunt.config(['coffee', 'all'], filepath)
^^^^^^^ You might have to change above line to:
grunt.config(['coffee', 'all', 'src'], filepath)
В вашей задаче coffeelint источники устанавливаются непосредственно под all
. Но в вашей задаче coffee
источники устанавливаются под all -> src
. Также может быть полезно отразить то же самое.
РЕДАКТИРОВАТЬ: Незначительное дополнение
Ответ 4
Вместо использования произвольного порога продолжительности вы можете сохранить каждое время модификации на карте:
fs = require 'fs'
mtimes = {}
isModified = (filepath) ->
mtime = fs.statSync(filepath).mtime
if mtimes[filepath]?
return mtimes[filepath] < mtime
else
mtimes[filepath] = mtime
return yes
Это слишком плохо, хотя этот хрюканье не предоставляет путь к файлу назначения в качестве второго аргумента функции фильтра. Это позволило бы простой проверке увидеть, существует ли сгенерированный файл и старше источника... Make делает это из коробки...