Grunt: mira varios archivos, comstack solo cambia

Soy nuevo en Grunt, y hasta ahora lo estoy disfrutando mucho. Quiero que Grunt compile solo los archivos modificados al ejecutar grunt watch

En mi Grunfile.coffee tengo actualmente (partes relevantes).
Nota: los activos / javascript / app.coffee y los activos / javascript / app.js son directorios

  coffee: default: expand: true cwd: "assets/javascript/app.coffee" src: ["*.coffee"] dest: "assets/javascript/app.js" ext: ".js" uglify: dev: options: beautify: true compress: false mangle: false preserveComments: 'all' files: "js/app.js": "assets/javascript/app.js/*.js" "js/libs.js": "assets/javascript/libs/*.js" watch: coffeescript: files: 'assets/javascript/**/*.coffee' tasks: ["coffee"] javascript: files: "assets/**/*.js" tasks: ["uglify:dev"] livereload: files: ["Gruntfile.coffee", "js/*.js", "*.php", "css/*.css", "images/**/*.{png,jpg,jpeg,gif,webp,svg}", "js/*.js", ] options: livereload: true 

Probablemente haya una forma más corta, pero primero compilo app.coffee a app.js, de modo que después de distribuir mi trabajo, las personas que no se sienten cómodas con Coffeescript pueden navegar el código de una manera bastante razonable.

El problema con todo esto es que ahora que guardo un archivo Coffeescript, recibo demasiados pasos (creo):

 >> File "assets/javascript/app.coffee/browse.coffee" changed. Running "coffee:default" (coffee) task File assets/javascript/app.js/browse.js created. File assets/javascript/app.js/filters.js created. Done, without errors. Completed in 0.837s at Tue May 28 2013 12:30:18 GMT+0300 (EEST) - Waiting... OK >> File "assets/javascript/app.js/browse.js" changed. >> File "assets/javascript/app.js/filters.js" changed. Running "uglify:dev" (uglify) task File "js/app.js" created. File "js/libs.js" created. Done, without errors. Completed in 0.831s at Tue May 28 2013 12:30:19 GMT+0300 (EEST) - Waiting... OK >> File "js/app.js" changed. >> File "js/libs.js" changed. Completed in 0.000s at Tue May 28 2013 12:30:19 GMT+0300 (EEST) - Waiting... 

Actualmente solo estoy configurando mi proyecto, pero tendré muchos más archivos de Coffeescript, y no quiero que Coffeescript recompile todos los archivos, en cada cambio de archivo.

Además, libs.js no tiene nada que ver con todo esto, pero supongo que todavía está comstackdo, porque también coincide con el patrón de “activos / * / .js”.

¿Hay alguna manera de hacer que Grunt compile solo los archivos que han cambiado?

¡Finalmente he encontrado una solución real! ¡Y es super simple también!

npm install grunt-newer --save-dev

Luego en tu Gruntfile (después de cargar la tarea en grunt):

 watch: coffeescript: files: 'assets/javascript/**/*.coffee' tasks: ["newer:coffee"] 

¡Y eso es! El asombroso gruñido-nuevo es increíble!

Si acumula todas las fonts .coffee en un archivo .js, tendrá que volver a comstackrlas cada vez que cambie alguna de sus fonts. Divídalo en varios archivos .js y realice una tarea de lanzamiento en la que solo cumpla estos archivos .js. De esta manera, solo necesitas incluir un archivo .js.

Consulte Uso de gruntjs, ¿cómo ver los cambios en los archivos .coffee?

El evento grunt.event.on detecta cambios en los archivos, recibiendo una action y un parámetro de filepath .

Aquí hay un ejemplo no probado basado en uno de mis archivos. En este caso, todos mis archivos de código fuente de coffeescript se guardan en un directorio llamado fonts, y para obtener una vista previa se comstackn y guardan en una estructura de directorios idéntica bajo un directorio llamado dev

 SOURCES_DIR = 'sources' DEV_DIR = 'dev' grunt.initConfig watch : all : files : ["**/*.coffee"] coffee : dev : files : dest : "app.js" grunt.loadNpmTasks 'grunt-contrib-watch' grunt.loadNpmTasks 'grunt-contrib-coffee' grunt.registerTask 'build', ['coffee:dev'] grunt.event.on('watch', (action,filepath) -> # Determine the full directory of the changed file wdi = filepath.lastIndexOf '/' wd = filepath.substring 0,wdi # remove `sources` prefix from that directory fpath = wd.replace(SOURCES_DIR,'') + '/' # determine the filename fnamei = filepath.lastIndexOf '.' fname = filepath.substring wdi+1,fnamei # NOTE: this breaks the case where in same dir # concatenate fpath and fname with the dir to be compiled into deststr = "#{DEV_DIR}#{fpath}#{fname}.coffee" # set coffee.dev.files value in the coffee task to have am entry of form {"destination":"source"} obj = {} obj[deststr] = filepath grunt.config "coffee.dev.files", obj # fire the coffee task grunt.task.run "coffee" ) 

Espero que ayude.

EDITAR: Probablemente no sea exactamente lo que quiere, porque sin duda desea acceder a variables intermedias, acciones, etc., pero podría usar el gruñido para ejecutar un comando de shell coffee. La tarea npm grunt-shell hace esto, por ejemplo

EDIT2: Me enfrenté a problemas continuos con grunt.watch.on no funciona de manera consistente en grunt 0.4.1 en OSX 10.8 y MacVim 7.3; Por alguna razón, deja de mirar. He vuelto a usar solo el objeto básico grunt initConfig pero con mucha más granularidad, por lo que solo mira y comstack grupos de archivos relativamente pequeños en lugar de todo el lote. Esto ralentiza considerablemente el tiempo de construcción, pero es mucho más robusto. Su kilometraje puede muy.

También me he topado con esto y no encontré ninguna versión funcional que funcionara con la versión actual (0.4.1) Pero la respuesta de Jof Arnolds mostró un buen enfoque.

Esto es lo que se me ocurrió:

 # only recompile changed files grunt.event.on "watch", (action, filepath) -> # note that we have to manually change the target file name to # our desired format targetName = filepath.replace(/\/(client|shared)/, "") .replace(".coffee", ".js") .replace("app/", "") options = src: filepath dest: "public/javascripts/#{targetName}" grunt.config ["coffee", "client"], options 

Tengo una sección de café que se parece a esto:

 coffee: client: options: sourceMap: false files: [ expand: true cwd: "app" src: ["*/client/**/*.coffee", "helpers/{client,shared}/*.coffee"] dest: "public/javascripts" rename: (folder, name) -> name = name.replace(/\/(client|shared)/, "") [folder, name].join path.sep ext: ".js" ]