Skip to content

Commit 54f6960

Browse files
committed
updates README.md
adds support for es2015 output format handlebars task throws the same errors than the master branch
1 parent 84e9d9e commit 54f6960

File tree

2 files changed

+150
-60
lines changed

2 files changed

+150
-60
lines changed

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,64 @@ var Handlebars = require('handlebars');
122122
var templates = require('./templates')(Handlebars);
123123
```
124124

125+
126+
#### es2015
127+
Type: `Boolean` or `Array`
128+
Default: `false`
129+
130+
Formats the output file as an ES2015 module, exports the result both as a named export as well as a default export.
131+
132+
For this option to work the `namespace` property needs to be defined.
133+
If not defined or explicitly set to `false`, the task's `namespace` property will instead default to `JST`.
134+
135+
136+
If `Array` then each array entry is expected to have both a variable and path properties:
137+
138+
```js
139+
es2015: [
140+
{variable: '$', path: 'jquery'},
141+
{variable: 'Handlebars', path: 'handlebars.runtime.js'},
142+
{variable: '{NamedModule}', path: 'my_module.js'}
143+
]
144+
```
145+
146+
Each of these will, in turn, be imported at the top of the compilation file:
147+
148+
149+
```js
150+
import $ from 'jquery';
151+
import Handlebars from 'handlebars.runtime.js';
152+
import {NamedModule} from 'my_module.js';
153+
```
154+
155+
If the es2015 property is a string, a function or `true` these imports will default to:
156+
157+
```js
158+
import Handlebars from 'handlebars.runtime.js';
159+
```
160+
161+
As you might know, you can't use `this` inside an es2015 module to reference the global scope. It's undefined as per specification.
162+
Instead of `this`, you can pass a `root` option to be used in its place.
163+
164+
```js
165+
options: {
166+
root: 'templates'
167+
}
168+
```
169+
170+
If said option isn't declared, the task's `root` property will default to `templates`
171+
172+
So, for example, if you use the default namespace `JST`, the compiled file will end with:
173+
174+
```js
175+
var JST = templates["JST"];
176+
export {JST};
177+
export default JST;
178+
```
179+
180+
The `root` option (albeit is not needed except for es2015 format) can be safely used with all output formats.
181+
182+
125183
#### processContent
126184
Type: `Function`
127185

tasks/handlebars.js

Lines changed: 92 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ module.exports = function(grunt) {
2525
// filename conversion for partials
2626
var defaultProcessPartialName = function(filepath) {
2727
var pieces = _.last(filepath.split('/')).split('.');
28-
var name = _(pieces).without(_.last(pieces)).join('.'); // strips file extension
28+
var name = _(pieces).without(_.last(pieces)).join('.'); // strips file extension
2929
if (name.charAt(0) === '_') {
3030
name = name.substr(1, name.length); // strips leading _ character
3131
}
@@ -62,9 +62,20 @@ module.exports = function(grunt) {
6262
amd: false,
6363
commonjs: false,
6464
knownHelpers: [],
65-
knownHelpersOnly: false
65+
knownHelpersOnly: false,
66+
es2015: false
6667
});
6768

69+
if (options.es2015) {
70+
// ES2015 doesn't allow to use "this" as root element
71+
options.root = options.root || 'templates';
72+
}
73+
if (options.es2015 || options.node) {
74+
// when using es2015 or node output format, the namespace option must be defined
75+
// Otherwise, it defaults to 'JST'
76+
options.namespace = options.namespace || 'JST';
77+
}
78+
6879
// assign regex for partials directory detection
6980
var partialsPathRegex = options.partialsPathRegex || /./;
7081

@@ -98,6 +109,10 @@ module.exports = function(grunt) {
98109
// nsdeclare options when fetching namespace info
99110
var nsDeclareOptions = {response: 'details', declared: nsDeclarations};
100111

112+
if (options.root) {
113+
nsDeclareOptions.root = options.root;
114+
}
115+
101116
// Just get the namespace info for a given template
102117
var getNamespaceInfo = _.memoize(function(filepath) {
103118
if (!useNamespace) {
@@ -111,78 +126,80 @@ module.exports = function(grunt) {
111126

112127
// iterate files, processing partials and templates separately
113128
f.src.filter(function(filepath) {
114-
// Warn on and remove invalid source files (if nonull was set).
115-
if (!grunt.file.exists(filepath)) {
116-
grunt.log.warn('Source file "' + filepath + '" not found.');
117-
return false;
118-
}
119-
return true;
120-
})
121-
.forEach(function(filepath) {
122-
var src = processContent(grunt.file.read(filepath), filepath);
123-
124-
var Handlebars = require('handlebars');
125-
try {
126-
// parse the handlebars template into it's AST
127-
ast = processAST(Handlebars.parse(src));
128-
compiled = Handlebars.precompile(ast, compilerOptions);
129-
130-
// if configured to, wrap template in Handlebars.template call
131-
if (options.wrapped === true) {
132-
compiled = 'Handlebars.template(' + compiled + ')';
129+
// Warn on and remove invalid source files (if nonull was set).
130+
if (!grunt.file.exists(filepath)) {
131+
grunt.log.warn('Source file "' + filepath + '" not found.');
132+
return false;
133133
}
134-
} catch (e) {
135-
grunt.log.error(e);
136-
grunt.fail.warn('Handlebars failed to compile ' + filepath + '.');
137-
}
138-
139-
// register partial or add template to namespace
140-
if (partialsPathRegex.test(filepath) && isPartialRegex.test(_.last(filepath.split('/')))) {
141-
filename = processPartialName(filepath);
142-
if (options.partialsUseNamespace === true) {
143-
nsInfo = getNamespaceInfo(filepath);
144-
if (nsInfo.declaration) {
145-
declarations.push(nsInfo.declaration);
134+
return true;
135+
})
136+
.forEach(function(filepath) {
137+
var src = processContent(grunt.file.read(filepath), filepath);
138+
139+
var Handlebars = require('handlebars');
140+
try {
141+
// parse the handlebars template into it's AST
142+
ast = processAST(Handlebars.parse(src));
143+
compiled = Handlebars.precompile(ast, compilerOptions);
144+
145+
// if configured to, wrap template in Handlebars.template call
146+
if (options.wrapped === true) {
147+
compiled = 'Handlebars.template(' + compiled + ')';
146148
}
147-
partials.push('Handlebars.registerPartial(' + JSON.stringify(filename) + ', ' + nsInfo.namespace +
148-
'[' + JSON.stringify(filename) + '] = ' + compiled + ');');
149-
} else {
150-
partials.push('Handlebars.registerPartial(' + JSON.stringify(filename) + ', ' + compiled + ');');
149+
} catch (e) {
150+
grunt.log.error(e);
151+
grunt.fail.warn('Handlebars failed to compile ' + filepath + '.');
151152
}
152-
} else {
153-
if ((options.amd || options.commonjs) && !useNamespace) {
154-
compiled = 'return ' + compiled;
155-
}
156-
filename = processName(filepath);
157-
if (useNamespace) {
158-
nsInfo = getNamespaceInfo(filepath);
159-
if (nsInfo.declaration) {
160-
declarations.push(nsInfo.declaration);
153+
154+
// register partial or add template to namespace
155+
if (partialsPathRegex.test(filepath) && isPartialRegex.test(_.last(filepath.split('/')))) {
156+
filename = processPartialName(filepath);
157+
if (options.partialsUseNamespace === true) {
158+
nsInfo = getNamespaceInfo(filepath);
159+
if (nsInfo.declaration) {
160+
declarations.push(nsInfo.declaration);
161+
}
162+
partials.push('Handlebars.registerPartial(' + JSON.stringify(filename) + ', ' + nsInfo.namespace +
163+
'[' + JSON.stringify(filename) + '] = ' + compiled + ');');
164+
} else {
165+
partials.push('Handlebars.registerPartial(' + JSON.stringify(filename) + ', ' + compiled + ');');
161166
}
162-
templates.push(nsInfo.namespace + '[' + JSON.stringify(filename) + '] = ' + compiled + ';');
163-
} else if (options.commonjs === true) {
164-
templates.push(compiled + ';');
165167
} else {
166-
templates.push(compiled);
168+
if ((options.amd || options.commonjs) && !useNamespace) {
169+
compiled = 'return ' + compiled;
170+
}
171+
filename = processName(filepath);
172+
if (useNamespace) {
173+
nsInfo = getNamespaceInfo(filepath);
174+
if (nsInfo.declaration) {
175+
declarations.push(nsInfo.declaration);
176+
}
177+
templates.push(nsInfo.namespace + '[' + JSON.stringify(filename) + '] = ' + compiled + ';');
178+
} else if (options.commonjs === true) {
179+
templates.push(compiled + ';');
180+
} else {
181+
templates.push(compiled);
182+
}
167183
}
168-
}
169-
});
184+
});
170185

171186
var output = declarations.concat(partials, templates);
172187
if (output.length < 1) {
173188
grunt.log.warn('Destination not written because compiled files were empty.');
174189
} else {
175-
if (useNamespace) {
176-
if (options.node) {
177-
output.unshift('Handlebars = glob.Handlebars || require(\'handlebars\');');
178-
output.unshift('var glob = (\'undefined\' === typeof window) ? global : window,');
179190

180-
var nodeExport = 'if (typeof exports === \'object\' && exports) {';
181-
nodeExport += 'module.exports = ' + nsInfo.namespace + ';}';
191+
if (options.root) {
192+
output.unshift('var ' + options.root + ' = ' + options.root + ' || {};');
193+
}
182194

183-
output.push(nodeExport);
184-
}
195+
if (options.node) {
196+
output.unshift('Handlebars = glob.Handlebars || require(\'handlebars\');');
197+
output.unshift('var glob = (\'undefined\' === typeof window) ? global : window,');
198+
199+
var nodeExport = 'if (typeof exports === \'object\' && exports) {';
200+
nodeExport += 'module.exports = ' + nsInfo.namespace + ';}';
185201

202+
output.push(nodeExport);
186203
}
187204

188205
if (options.amd) {
@@ -225,6 +242,21 @@ module.exports = function(grunt) {
225242
output.push('};');
226243
}
227244

245+
if (options.es2015) {
246+
247+
if (Array.isArray(options.es2015)) {
248+
options.es2015.forEach(function(dependency) {
249+
output.unshift('import ' + dependency.variable + ' from \'' + dependency.path + '\';');
250+
});
251+
} else {
252+
output.unshift('import Handlebars from \'handlebars\';');
253+
}
254+
255+
output.push('var ' + options.namespace + ' = ' + nsInfo.namespace + ';');
256+
output.push('export {' + options.namespace + '};');
257+
output.push('export default ' + options.namespace + ';');
258+
}
259+
228260
filesCount++;
229261
grunt.file.write(f.dest, output.join(grunt.util.normalizelf(options.separator)));
230262
grunt.verbose.writeln('File ' + chalk.cyan(f.dest) + ' created.');

0 commit comments

Comments
 (0)