Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gruntfile.js building file object dynamically

Tags:

gruntjs

Problem: On the Grunt project's "Configuring Tasks" page, the "Files Object Format" way of specifying files for a task worked, while the "Files Array Format" and, critically, the "Building the file object dynamically" way (see the "dynamic_mappings" section of their listing) did not.

Questions: why does listing #2 not work? is the dynamic-file-building example on Grunt's page wrong?

Reference: the Grunt project page at Configuring Tasks / Building the Files Object Dynamically.

At bottom are two listings for a Gruntfile.js. The first one does not work, while the second one does. The only difference between them is in how each specifies the "files" task:

files: [{
  expand: true,
  cwd: 'views/',
  src: ['**/*.jade'],
  dest: 'html/',
  ext: 'html',
}],

... the one that works reads:

files: {
  expand: true,
  cwd: 'views/',
  src: ['**/*.jade'],
  dest: 'html/',
  ext: 'html',
},

The only difference lies in the presence/absence of "[" and "]".

The second listing does not work, but does follow the example at Grunt project's page at Configuring Tasks / Building the Files Object Dynamically.

Listing # 1 (does not work): aborts with "Warning: Object # has no method 'indexOf' Use --force to continue."

module.exports = function(grunt) {

    grunt.initConfig({

        jade: {
            options: { pretty: true,
                data: {
                  debug: true,
                  timestamp: "<%= grunt.template.today() %>"
                }
            },
            files: [{
              expand: true,
              cwd: 'views/',
              src: ['**/*.jade'],
              dest: 'html/',
              ext: 'html',
            }],
        },

        watch: {
            html: {
                files: ['handlers/**/*.js', 'views/**/*.jade', 'app.js'],
                tasks: ['jade']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-jade');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('default', ['jade', 'watch']);

}

Listing # 2 (works):

module.exports = function(grunt) {

    grunt.initConfig({

        jade: {
            options: { pretty: true,
                data: {
                  debug: true,
                  timestamp: "<%= grunt.template.today() %>"
                }
            },
            files: {
              expand: true,
              cwd: 'views/',
              src: ['**/*.jade'],
              dest: 'html/',
              ext: 'html',
            },
        },

        watch: {
            html: {
                files: ['handlers/**/*.js', 'views/**/*.jade', 'app.js'],
                tasks: ['jade']
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-jade');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('default', ['jade', 'watch']);

}
  • "lucky" = spent the weekend reading hundreds of pages about parsing errors, grunt, jade, express, JavaScript, functions and objects... finally deciding that since every reasonable effort had failed, the only thing left to try was the unreasonable.
like image 502
HisHighnessDog Avatar asked Sep 16 '13 04:09

HisHighnessDog


2 Answers

Answer (added after I posted the question):

The required structure of CONFIG (grunt.initConfig) is:

 CONFIG
    TASK
       TARGET
          FILES               // MUST be child of a target
          OPTIONS             // MUST be child of a target

So this should not work (but does.. I got lucky*):

 grunt.initConfig
    jade: {
       files: {...           // all info content required for jade...
     options: ...            // is specified in these two elements

... and this should not work (and doesn't... whew!):

 grunt.initConfig
    jade: {
       files: [ {...
     options: ...

Finally, this should and does work (hallelujah):

 grunt.initConfig
    jade: {
      foo: {      // MUST have target, though no addn'l info added. why? just because.
         files: ...
         options: ...
like image 92
HisHighnessDog Avatar answered Nov 04 '22 08:11

HisHighnessDog


I had a similar problem and found the answer in this posting to work (after I rearranged the structure as posted here)

Referring to Grunt targets resulting in Warning: Object true has no method 'indexOf'

Essentially, the answer is to wrap the definition part of the files directive as an array. Instead of

files:{...}  

use

files:[{...}]
like image 1
Bryan Avatar answered Nov 04 '22 07:11

Bryan