❝Inventory of solutions to modularize grunt configuration for large project & (legacy) codebases❞…

/198290

  • Usable and flexible Gruntfile modularization

    La suite et le début de la fin de mes interrogations sur la modularisation de la configuration et des tâches #grunt, pour un gros projet de « refactoring »

    Je voulais quelque chose de simple, qui autorise un découpage orienté fonctionnalité, maintenable et facilitant l’appropriation par les integrateurs / devs front de l’équipe.

    Plutôt que d’avoir un énorme Gruntfile inmaintenable et incompréhensible, on le découpe en petits morceaux consistants avec l’organisation fonctionnelle du site.

    https://gist.github.com/0gust1/7683132

    /*global module:false*/
    module.exports = function(grunt) {
    var env = process.env.NODE_ENV || 'dev';
    var _ = require('lodash');
    /*** External config & tasks filepaths ***/
    //we have 1 base config, and possibly many module-specific config
    var configLocations = ['./grunt-config/default_config.js', './grunt-config/**/config.js'];
    //we have 1 base tasks definition, and possibly many module-specific config
    var tasksLocations = ['./grunt-config/default_tasks.js', './grunt-config/**/tasks.js'];
    /* Typical project layout (matching with the globbing pattern above - adapt to your project structure) :
    
      ├── Gruntfile.js 
      ├── package.json
      ├── grunt-config
      │   ├── homepage
      │   │   └── config.js
      │   ├── navigation
      │   │   └── config.js
      │   ├── module1
      │   │   ├── config.js
      │   │   └── tasks.js
      │   ├── default_config.js
      │   ├── default_tasks.js
      │   └── template_module_grunt.txt
      ├── website_directory1
      │   ├── mdp
      │   ├── multimedia-storage
      │   ├── mv-commit.sh
      │   ├── query
      │   ├── temp
      │   └── tmp
      └── website_directory2
          ├── crossdomain.xml
          ├── css
          ├── favicon.ico
          ├── fonts
          :
          :
          :
    
      */
    /***************** External configuration management ***********************************/
    var configFiles = grunt.file.expand({
    filter: "isFile"
    }, configLocations );
    grunt.log.writeln('Gathering external configuration files'.underline.green);
    grunt.log.writeln("configFiles : " + grunt.log.wordlist(configFiles, {
    separator: ', ',
    color: 'cyan'
    }));
    var configArray = configFiles.map(function(file) {
    grunt.log.writeln("=> importing : " + file);
    return require(file)(grunt, env);
    });
    var config = {};
    configArray.forEach(function(element) {
    config = _.merge(config, element);
    });
    grunt.initConfig(config);
    /***************** Task loading & registering *******************************************/
    // We load grunt tasks listed in package.json file
    require('load-grunt-tasks')(grunt);
    /****** External tasks registering ****************/
    grunt.log.writeln('Gathering external task files'.underline.green);
    var taskFiles = grunt.file.expand({
    filter: "isFile"
    }, tasksLocations);
    grunt.log.writeln("task files : " + grunt.log.wordlist(taskFiles, {
    separator: ', ',
    color: 'cyan'
    }));
    taskFiles.forEach(function(path) {
    grunt.log.writeln("=> loading & registering : " + path);
    require(path)(grunt);
    });
    grunt.registerTask('default', ['attention:gruntfile', 'jshint:gruntfile', 'logConfig']);
    grunt.registerTask('checkGruntFile', 'Tâche par défaut - aide et vérification du gruntfile', function() {
    grunt.log.subhead('* Tâche par défaut - aide et vérification du gruntfile *');
    grunt.log.writeln('Exécutez "grunt -h" pour avoir plus d\'informations sur les tâches disponibles');
    grunt.log.writeln('...');
    grunt.log.subhead('Vérification du gruntfile...');
    grunt.task.run(['jshint:gruntfile']);
    });
    //write the generated configuration (for debug)
    grunt.registerTask('logConfig', 'Ecrire la configuration générée', function() {
    //grunt.task.run(['attention:gruntfile']);
    grunt.log.subhead('* Configuration générée : *');
    grunt.log.writeln(JSON.stringify(config, undefined, 2));
    });
    };

    Pour le début de ma démarche : http://seenthis.net/messages/198290

    #javascript #webdev #front_end #node_js

    • Juste pour dire que j’ai corrigé un bug dans le chargement des fichiers de tâche (’grunt.task.loadTasks()’ ne prend pas/plus en paramètre un filepath mais un path, ce qui foutait tout par terre). Désormais j’utilise ’require()’.

      Attention, du coup l’embed sur @seenthis n’est plus à jour.