Search code examples
gruntjsgrunt-contrib-concatgrunt-contrib-copy

Running tasks sequentially in Grunt


I was under the impression that in grunt.registerTask(taskName, taskList) the taskList would run sequentially (i.e. one completes before moving onto the next). I guess that is not the case?

Given this task:

grunt.registerTask('local-debug', [
    'clean',
    'concat:local',
    'ngconstant:common',
    'targethtml:local',
    'copy:debug'
]);

How can I make sure that concat/ngconstant/targethtml are complete before running copy? I'm having issues because the ngconstant is running before the concat has finished.

Edit: Details that tasks are not running sequentially.

'concat:local' creates a aggregate.json file used by 'ngconstant:common'. If I delete the existing aggregate.json file, the ngconstant:common task errors because the aggregate.json file is missing (but the file does get created, just after ngconstant runs). Also, if I don't delete the file, and just make a change like changing the version number in a source file that concat uses, the file created by ngconstant does not pick up the change because it does not wait until the new aggregate.json is created by concat.

Edit 2: task code

concat: {
        options: {
            banner: '{"appConfig": {',
            footer: "}}",
            separator: ','
        },
        local: {
            src: ["app/config/common-config.json", "app/config/local.json"],
            dest: "app/config/aggregate-config.json"
        }
    },
ngconstant: {
        options: {
            space: '  ',
            wrap: '(function(){\n\n"use strict";\n\n {%= __ngModule %}\n\n}());',
            name: 'CoreConfig',
            dest: 'app/scripts/config.js'
        },
        common: {
            constants: grunt.file.readJSON('app/config/aggregate-config.json')
        }
}

Solution

  • OK, got it.

    Grunt works by following the below steps:

    1. its whole Gruntfile is read and the config is evaluated
    2. then it builds the list of tasks to run
    3. then it goes through the list, running tasks in sequence

    So what happens is that your during 1., your file aggregate-config.json is read and sets config.ngconstant.common.constants to its current value (the result from your PREVIOUS run). Then 3. happens, and a new aggregate-config.json is generated, but not used (config is NOT re-read between tasks).

    But if you pass a string to ngconstant.constants, it is interpreted as a file name and read when the task is run (step 3), getting you the result you want:

    ngconstant: {
      common: {
        constants: 'app/config/aggregate-config.json'
      }
    }