grunt-contrib-handlebars
grunt-contrib-handlebars copied to clipboard
Using commonjs:true generates incorrect JS code (0.10.2)
Using v0.10.2, if commonjs:true
is set in options, then the output module JS file puts each template into a return
statement, so the resulting file has multiple returns from the same function.
Gruntfile.js:
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
handlebars: {
compile: {
files: [{
dest: 'dist/templates.js',
src: 'src/**/*.hbs'
}],
options: {
commonjs: true,
namespace: false
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-handlebars');
grunt.registerTask('default', ['handlebars:compile']);
};
The /src
directory contains 2 files:
src/one.hbs
<h1>template one</h1>
src/two.hbs
<h2>template two</h2>
The resulting dist/templates.js
is:
module.exports = function(Handlebars) {
return Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<h1>template one</h1>";
},"useData":true});
return Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<h2>template two</h2>";
},"useData":true});
};
Note that the generated function has 2 return
statements, one for each template.
module.exports = function(Handlebars) {
return Handlebars.template(...
return Handlebars.template(...
}
This was discovered after an upgrade from v0.9.1 (which used Handlebars 2) to v0.10.2 (which uses Handlebars 3)
If I backdate grunt-contrib-handlebars to v0.9.1 then the generated dist/templates.js
file is:
module.exports = function(Handlebars) {
var templates = {};
templates["src/one.hbs"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<h1>template one</h1>";
},"useData":true});
templates["src/two.hbs"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<h2>template two</h2>";
},"useData":true});
return templates;
};
which is the correct/expected output.
Workaround is to add a namespace
option set to a string. Then the generated code is usable.
For example, with the option namespace:'templates'
:
module.exports = function(Handlebars) {
this["templates"] = this["templates"] || {};
this["templates"]["src/one.hbs"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<h1>template one</h1>";
},"useData":true});
this["templates"]["src/two.hbs"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<h2>template two</h2>";
},"useData":true});
return this["templates"];
};
We have stumbled on this pretty hard. While the workaround works it does not work as it says in the documentation.