Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80684 views
1
2
var fs = require('fs'),
3
Handlebars = require('./index'),
4
basename = require('path').basename,
5
SourceMap = require('source-map'),
6
SourceMapConsumer = SourceMap.SourceMapConsumer,
7
SourceNode = SourceMap.SourceNode,
8
uglify = require('uglify-js');
9
10
module.exports.cli = function(opts) {
11
if (opts.version) {
12
console.log(Handlebars.VERSION);
13
return;
14
}
15
16
if (!opts.templates.length) {
17
throw new Handlebars.Exception('Must define at least one template or directory.');
18
}
19
20
opts.templates.forEach(function(template) {
21
try {
22
fs.statSync(template);
23
} catch (err) {
24
throw new Handlebars.Exception('Unable to open template file "' + template + '"');
25
}
26
});
27
28
if (opts.simple && opts.min) {
29
throw new Handlebars.Exception('Unable to minimize simple output');
30
}
31
if (opts.simple && (opts.templates.length !== 1 || fs.statSync(opts.templates[0]).isDirectory())) {
32
throw new Handlebars.Exception('Unable to output multiple templates in simple mode');
33
}
34
35
// Convert the known list into a hash
36
var known = {};
37
if (opts.known && !Array.isArray(opts.known)) {
38
opts.known = [opts.known];
39
}
40
if (opts.known) {
41
for (var i = 0, len = opts.known.length; i < len; i++) {
42
known[opts.known[i]] = true;
43
}
44
}
45
46
// Build file extension pattern
47
var extension = opts.extension.replace(/[\\^$*+?.():=!|{}\-\[\]]/g, function(arg) { return '\\' + arg; });
48
extension = new RegExp('\\.' + extension + '$');
49
50
var output = new SourceNode();
51
if (!opts.simple) {
52
if (opts.amd) {
53
output.add('define([\'' + opts.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n Handlebars = Handlebars["default"];');
54
} else if (opts.commonjs) {
55
output.add('var Handlebars = require("' + opts.commonjs + '");');
56
} else {
57
output.add('(function() {\n');
58
}
59
output.add(' var template = Handlebars.template, templates = ');
60
if (opts.namespace) {
61
output.add(opts.namespace);
62
output.add(' = ');
63
output.add(opts.namespace);
64
output.add(' || ');
65
}
66
output.add('{};\n');
67
}
68
function processTemplate(template, root) {
69
var path = template,
70
stat = fs.statSync(path);
71
if (stat.isDirectory()) {
72
fs.readdirSync(template).map(function(file) {
73
var path = template + '/' + file;
74
75
if (extension.test(path) || fs.statSync(path).isDirectory()) {
76
processTemplate(path, root || template);
77
}
78
});
79
} else {
80
var data = fs.readFileSync(path, 'utf8');
81
82
if (opts.bom && data.indexOf('\uFEFF') === 0) {
83
data = data.substring(1);
84
}
85
86
var options = {
87
knownHelpers: known,
88
knownHelpersOnly: opts.o
89
};
90
91
if (opts.map) {
92
options.srcName = path;
93
}
94
if (opts.data) {
95
options.data = true;
96
}
97
98
// Clean the template name
99
if (!root) {
100
template = basename(template);
101
} else if (template.indexOf(root) === 0) {
102
template = template.substring(root.length+1);
103
}
104
template = template.replace(extension, '');
105
106
var precompiled = Handlebars.precompile(data, options);
107
108
// If we are generating a source map, we have to reconstruct the SourceNode object
109
if (opts.map) {
110
var consumer = new SourceMapConsumer(precompiled.map);
111
precompiled = SourceNode.fromStringWithSourceMap(precompiled.code, consumer);
112
}
113
114
if (opts.simple) {
115
output.add([precompiled, '\n']);
116
} else if (opts.partial) {
117
if(opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
118
output.add('return ');
119
}
120
output.add(['Handlebars.partials[\'', template, '\'] = template(', precompiled, ');\n']);
121
} else {
122
if(opts.amd && (opts.templates.length == 1 && !fs.statSync(opts.templates[0]).isDirectory())) {
123
output.add('return ');
124
}
125
output.add(['templates[\'', template, '\'] = template(', precompiled, ');\n']);
126
}
127
}
128
}
129
130
opts.templates.forEach(function(template) {
131
processTemplate(template, opts.root);
132
});
133
134
// Output the content
135
if (!opts.simple) {
136
if (opts.amd) {
137
if(opts.templates.length > 1 || (opts.templates.length == 1 && fs.statSync(opts.templates[0]).isDirectory())) {
138
if(opts.partial){
139
output.add('return Handlebars.partials;\n');
140
} else {
141
output.add('return templates;\n');
142
}
143
}
144
output.add('});');
145
} else if (!opts.commonjs) {
146
output.add('})();');
147
}
148
}
149
150
151
if (opts.map) {
152
output.add('\n//# sourceMappingURL=' + opts.map + '\n');
153
}
154
155
output = output.toStringWithSourceMap();
156
output.map = output.map + '';
157
158
if (opts.min) {
159
output = uglify.minify(output.code, {
160
fromString: true,
161
162
outSourceMap: opts.map,
163
inSourceMap: JSON.parse(output.map)
164
});
165
if (opts.map) {
166
output.code += '\n//# sourceMappingURL=' + opts.map + '\n';
167
}
168
}
169
170
if (opts.map) {
171
fs.writeFileSync(opts.map, output.map, 'utf8');
172
}
173
output = output.code;
174
175
if (opts.output) {
176
fs.writeFileSync(opts.output, output, 'utf8');
177
} else {
178
console.log(output);
179
}
180
};
181
182