dmathisen
dmathisen

Reputation: 2342

Dynamic Grunt Watch configuration

My site file structure is something like this:

app
    less
        themes
            default
            modern
            etc
public
    themes
        default
            css
        modern
            css
        etc

So /app/less/themes/{{ themeName }}/*.less will compile into /public/themes/{{ themeName }}/css/*.css.

I have my Grunt Less task set up dynamically and working fine. Example: grunt less:compileTheme:modern

less: {
  compileTheme: {
    options: {
      compress: false,
      yuicompress: false,
      optimization: 2,
      sourceMap: true,
      sourceMapFilename: "public/themes/<%= grunt.task.current.args[0] %>/css/styles.css.map",
      sourceMapURL: "/themes/<%= grunt.task.current.args[0] %>/css/styles.css.map"
    },
    files: {
      "public/themes/<%= grunt.task.current.args[0] %>/css/styles.css": "app/less/themes/<%= grunt.task.current.args[0] %>/styles.less"
    }
  }
}

But I'm not sure how to get the Grunt Watch task working. Ideally, it'll see the theme folder name and run the grunt task as grunt less:compileTheme:{{ themeName }}:

watch: {
    themeCss: {
        files: "app/less/themes/{{ themeName }}/**/*.less",
        tasks: ["less:compileTheme:{{ themeName }}"],
        options: {
          spawn: false
        }
    }
}

Is this possible? And/or is there a better way I should be doing this?

Upvotes: 0

Views: 294

Answers (1)

hereandnow78
hereandnow78

Reputation: 14434

edit your watch task to run the less:compileTheme-task without themeName, and watch all less files in your themes folder:

watch: {
    themeCss: {
        files: "app/less/themes/**/*.less",
        tasks: ["less:compileTheme"],
        options: {
          spawn: false
        }
    }
}

now you can add a watch event-handler where you get the changed file. extract the themeName, and configure your less-task:

grunt.event.on('watch', function(action, filepath) {
  var themeName = filepath.split('/')[3];
  grunt.config('less.compileTheme.files', {
    "public/themes/" + themeName + "/css/styles.css": "app/less/themes/" + themeName + "/styles.less"
  });
});

of course the detection of your themeName should be more reliable, but i think you get the idea on how to do dynamic watching!

Upvotes: 1

Related Questions