Search code examples
javascriptgruntjsgrunt-contrib-concatload-order

grunt-contrib-concat: specify last file to be concatenated?


I'm using grunt-contrib-concat to concatenate all my custom JS files together, and wrap them with an IIFE. I'm running into some load order issues ( namely, my init file is executing before some modules, causing undefined errors ). I want to specify init.js should be LAST in the concat order, but I don't want to specify the order for all the other JS files as well, just that this specific one goes last.

Here is the current config of my concat:

/**
 * Set project info
 */
project: {
  src: 'src',
  app: 'app',
  assets: '<%= project.app %>/assets',
  css: [
    '<%= project.src %>/scss/style.scss'
  ],
  js: [
    '<%= project.src %>/js/*.js'
  ]
},

concat: {
  dev: {
    files: {
      '<%= project.assets %>/js/scripts.min.js': '<%= project.js %>'
    }
  },
  options: {
    stripBanners: true,
    nonull: true,
    banner: ';(function($, window, document, undefined){ \n "use strict";',
    footer: '}(jQuery, window, document));'
  }
},

How do I specify a last file to be concatenated without adding an extra grunt module to my project?


Solution

  • You can do it by concatenating all files but init.js, and then concatenating the result with init.js, using the array syntax that maintains order:

    concat: {
        dev1: {
            dest: '<tmp>/concat1.js',
            src: ['<all your js>', '!init.js']
        },
        devFinal: {
            options: {
                stripBanners: true,
                nonull: true,
                banner: ';(function($, window, document, undefined){ \n "use strict";',
                footer: '}(jQuery, window, document));'
            },
            files: {
                dest: 'scripts.min.js',
                src: ['<tmp>/concat1.js', 'init.js']
            },
        },
    }
    

    And then call both targets in succession:

    grunt.registerTask('myConcat', ['concat:dev1', 'concat:devFinal']);