Skip to content

Instantly share code, notes, and snippets.

@cspotcode
Last active April 25, 2016 05:44
Show Gist options
  • Save cspotcode/c333e6eedbe82f713f85 to your computer and use it in GitHub Desktop.
Save cspotcode/c333e6eedbe82f713f85 to your computer and use it in GitHub Desktop.
Grunt template functions (alternative to template strings)

What if we could use inline functions alongside grunt template strings?

var tmpl = grunt.template.fn;
grunt.initConfig({
    // Simple usage: wrap a function in a call to grunt.template.fn()
    foo: tmpl(function() {return {/* some computed config value */}}),
    
    // Using es6 arrow functions
    bar: tmpl(=> {/* some computed config value */}}),
    
    // with template strings, any logic isn't allowed when you want your template to yield a non-string value
    baz: '<%= prop.subprop %>'
});

When grunt config is fetched, and templates are processed, the wrapped functions are executed and their return value used in the grunt config.

##Benefits:

Grunt templates are good because they are processed at the time config is fetched, not at the time the gruntfile is initally executed. However, they're strings and so IDEs don't understand the code.

Gruntfiles are great because they're plain JS code so you can do loops, dynamic task generation, etc. However, execution can't be deferred till when a task runs, so config can only be programmatically generated at startup time.

This approach, using wrapped functions, has the best of both worlds.

The idea is to avoid "stringly typed" code, using normal Javascript instead. IDE intellisense and refactoring work better on code than strings.

module.exports = function(grunt) {
// Store a reference to the template function constructor
var tmpl = grunt.template.fn;
grunt.initConfig({
// support running "copy:dev:blog", "copy:dev:homepage" or "copy:dev:contactForm"
copy: {
dev: {
files: [tmpl(=> { // look ma, all Javascript! No code hiding in strings.
blog: {
expand: true
cwd: 'src/blog',
src: '**/*',
dest: 'dest/blog'
},
homepage: {
expand: true,
cwd: 'src/main',
src: '**/*.@{png,html,js,css}',
dest: 'dest/home'
},
contactForm: {
expand: true,
cwd: 'src/contact',
dest: 'dest/contact'
}[grunt.task.current.args[0]]
}]
}
}
});
}
@Klortho
Copy link

Klortho commented Apr 24, 2016

Is this a real thing I can use? I think it wouldn't be hard to implement, but it would be easier to npm i --save-dev, of course.

@Klortho
Copy link

Klortho commented Apr 25, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment