web-dev-qa-db-fra.com

Comment regardez-vous plusieurs fichiers, mais n'exécutez-vous la tâche que sur le fichier modifié, dans Grunt.js?

En apprenant à utiliser grunt , j'essaie de faire un simple observateur/compilateur de script de café. Le problème est que si je dis à la tâche watch de regarder plusieurs fichiers, et que l'un change, il va passer tous les fichiers à la commande coffee. Cela signifie que lorsque vous changez 1 fichier, il va recompiler tous des fichiers correspondant au modèle src. Au lieu de cela, je souhaite recompiler uniquement le fichier unique qui a changé et qui correspond au modèle src.

Voici la grunt.js:

module.exports = function(grunt) {
  grunt.initConfig({
    coffee: {
      app: {
        src: ['test/cases/controller/*.coffee'],
        dest: 'tmp',
        options: {
          bare: true,
          preserve_dirs: true
        }
      }
    },
    watch: {
      files: ['<config:coffee.app.src>'],
      tasks: ['coffee:app']
    }
  });

  grunt.loadNpmTasks('grunt-coffee');
  grunt.registerTask('default', 'coffee');
};

Cela utilise grunt-coffee , qui est essentiellement le suivant: https://Gist.github.com/2373159 .

Quand je lance grunt watch, et j'enregistre un fichier dans test/cases/controller/*.coffee, il compile tous des fichiers correspondants (en les mettant dans tmp/*).

Comment pouvez-vous plutôt compiler uniquement le fichier modifié en utilisant grunt?

43
Lance Pollard

Le grunt à venir (et actuellement en développement) v0.4.0a a l'objet grunt.file.watchFiles , qui a été conçu expressément à cet effet. Le plugin grunt-coffee a peut-être déjà ajouté la prise en charge de cette fonctionnalité, je ne suis pas sûr.

Quoi qu'il en soit, si vous êtes intéressé à essayer une version en développement de grunt dans votre projet, consultez le Quand pourrai-je utiliser la fonctionnalité en développement 'X'? FAQ entrée.

15
Cowboy Ben Alman

J'ai obtenu ce travail lors de la compilation de mes fichiers less. Vous devriez pouvoir jouer un peu avec cette configuration pour la faire fonctionner avec le plugin coffeescript. La partie qui nous intéresse est la grunt.event.on('watch', ...). Dans ce gestionnaire d'événements, je mets à jour la propriété files dans la commande less pour ne contenir que le fichier modifié.

path = require('path');

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    less: {
      development: {
        options: {
          paths: ["./library/less"],
        },
        files: [
          { src: "./library/less/bootstrap.less", dest: "./library/css/bootstrap.css"},
          { src: "./library/less/app.less", dest: "./library/css/app.css"}
        ]
      }
    },

    watch: {
      styles: {
        files: "./library/less/*",
        tasks: ["less"],
        options: {
          nospawn: true,
        },
      },
    },
  });

  // Event handling
  grunt.event.on('watch', function(action, filepath){
    // Update the config to only build the changed less file.
    grunt.config(['less', 'development', 'files'], [
      {src: filepath, dest: './library/css/' + path.basename(filepath, '.less') + '.css'}
    ]);
  });

  // Load the plugins
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Tasks
  grunt.registerTask('default', ['watch']);
};
8
blachniet

Aucune de ces réponses n'a très bien fonctionné pour moi. Voici ma solution si quelqu'un est intéressé (je sais que je suis un peu en retard pour répondre à cette question).

https://Gist.github.com/ryansmith94/8569178

4
Ryan Smith

https://github.com/tschaub/grunt-newer ressemble exactement à des tâches similaires:

Configurez les tâches Grunt pour qu'elles s'exécutent avec des fichiers plus récents uniquement.

Synopsis: La tâche la plus récente configurera une autre tâche à exécuter avec des fichiers src qui sont a) plus récents que les fichiers dest ou b) plus récents que la dernière exécution réussie (s'il n'y a pas de fichiers dest). Voir ci-dessous pour des exemples et plus de détails.

Vous pouvez ajouter facilement à n'importe quelle tâche. Dans ton cas:

  grunt.loadNpmTasks('grunt-newer');
  grunt.registerTask('default', 'newer:coffee');
3
Lajos Veres

Dans ce issue , Kyle Robinson suggère d'utiliser le watchevent. Il est très important de définir la propriété de la tâche de surveillance nospawn sur true pour que cela fonctionne. J'ai modifié sa solution pour exécuter sélectivement les tâches:

grunt.event.on('watch', function(action, filepath) {
    if (minimatch(filepath, grunt.config('watch.stylesheets.files'))) {
        grunt.config('compass.dist.options.specify', [filepath]);
    }

    if (minimatch(filepath, grunt.config('watch.scripts.files'))) {
        var uglifySrc = filepath.replace(grunt.config('uglify.dist.cwd'), '');
        grunt.config('jshint.dist.src', [filepath]);
        grunt.config('uglify.dist.src', [uglifySrc]);
    }
});

Voici la solution complète: https://Gist.github.com/luissquall/5408257

3
luissquall

La tâche grunt-contrib-watch prend désormais en charge cela.

https://npmjs.org/package/grunt-contrib-watch -> recherchez "Compilation des fichiers selon les besoins"

grunt.initConfig({
  watch: {
    scripts: {
      files: ['lib/*.js'],
      tasks: ['jshint'],
      options: {
        nospawn: true,
      },
    },
  },
  jshint: {
    all: ['lib/*.js'],
  },
});

// on watch events configure jshint:all to only run on changed file
grunt.event.on('watch', function(action, filepath) {
  grunt.config(['jshint', 'all'], filepath);
});

Cela devrait empêcher les tâches de compiler tous les fichiers à chaque fois que quelque chose change.

2
smets.kevin

Donc, nouveau dans Grunt 0.4 est plus de tâches nommées

Laissez-nous vous donner un exemple!

watch: {
    package1: {
        files: [
            './modules/package1/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
    package2: {
        files: [
            './test_packages/package2/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
    package3: {
        files: [
            './test_packages/package3/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
}

Pour exécuter toutes ces tâches de surveillance, faites simplement grunt.registerTask ('default', ['myInitialBuild', 'watch']);

myInitialBuild est la construction initiale (tous les fichiers), puis suivez-la avec une montre sur chaque paquet. En réalité, vous pouvez le faire pour chaque fichier, mais cela semble insensé.

2
Michael