Grunt watch those templates
- 1. Purpose
- 2. Starting to watch
- 3. Compiling EJS templates
- 4. Compiling Handlebars templates
- 5. Final Gruntfile.js
Purpose
Setting up automatic EJS (Underscore/Lo-Dash) and Handlebars template compilation in Grunt using grunt-contrib-watch.
The aim is to be able to spawn a process which will watch our templates and compile them to JST (Javascript template) files while we’re editing them. That way we can write our templates in a more readable fashion but use the actual JST files at runtime (thus avoiding the need to compile them dynamically).
Starting to watch
cd into an empty directory and:
1 | $ npm init |
Start the Gruntfile.js configuration with the following, just to check that watch is working:
vim Gruntfile.js
1 | 'use strict'; |
Running grunt watch and editing a JS file in ‘app/scripts/**/*.js’ (e.g. app/scripts/tmp.js) should give the following output:
Compiling EJS templates
Replace watch’s log option with the following:
1 | jst: { |
Configure JST compilation for EJS files with the following (don’t include amd: true if you’re not working with an AMD module loader like RequireJS):
1 | jst: { |
Personally, I find using jst for the key a bit confusing. The way I understand it is that both grunt-contrib-jst and grunt-contrib-handlebars, as well as any other JST compiler, compiles some kind of template file to a Javascript file in order to make the authoring and maintaing of these JST files easier (since these Javascript files tend to be heavy on string concatenation and such).
Since grunt-contrib-jst compiles EJS templates, it seems to me that it would have made more sense to call the plugin grunt-contrib-ejs and to use ejs as the key to configure this plugin in grunt.initConfig. But the key to use for the plugin is jst, so I’m also sticking to jst in the watch plugin configuration. I will, however, be suffixing these template files with .ejs, hence the above configuration.
Running grunt watch and editing an EJS file in our watched path should trigger the compilation, e.g:
vim app/scripts/templates/ejs/tmp.ejs
1 | <ul> <% for(var i=0; i<supplies.length; i++) { %> <li> <a href='supplies/<%= supplies[i] %>'> <%= supplies[i] %> </a> </li> <% } %> </ul> |
Compiling Handlebars templates
Add the following option to the watch task configuration:
1 | handlebars: { |
Then configure the grunt-contrib-handlebars plugin itself (again, I want the generated JST file to be wrapped in an AMD define, YMMV):
1 | handlebars: { |
Try it out:
vim app/scripts/templates/hbs/tmp.hbs
… and assuming you’ve restarted grunt watch and it’s running in the background, you should get hbsTemplates.js.
Final Gruntfile.js
1 | 'use strict'; |