Reputation: 274
I'm trying to compile all my .jade templates into a single js file, I'm using Gulpjs and gulp-jade, gulp-concat..
I can get the single file but the problem is that all the functions rendered there have the same name, they are all called "template".
foo.jade:
.fooDiv
h1 Foo here
foo2.jade:
.foo2Div
h1 Foo2 here
Gulp file:
gulp.src("templates/**/*.jade")
.pipe(jade({client: true}))
.pipe(concat("templates.js"))
.pipe(gulp.dest("../website/templates"))
That would output a file like this:
function template(locals) {
var buf = [];
var jade_mixins = {};
buf.push("<div class=\"fooDiv\"><h1>Foo here</h1></div>");;return buf.join("");
}
function template(locals) {
var buf = [];
var jade_mixins = {};
buf.push("<div class=\"foo2Div\"><h1>Foo2 here</h1></div>");;return buf.join("");
}
And what I want is something like:
function foo(locals) {
var buf = [];
var jade_mixins = {};
buf.push("<div class=\"fooDiv\"><h1>Foo here</h1></div>");;return buf.join("");
}
function foo2(locals) {
var buf = [];
var jade_mixins = {};
buf.push("<div class=\"foo2Div\"><h1>Foo2 here</h1></div>");;return buf.join("");
}
Is there any way I can do this? I've been searching for quite some time now and didn't find anything.
Cheers. Caio
Edit:
Jade now accepts the name option for jade.compileClient. Check it here: https://github.com/jadejs/jade/blob/master/jade.js
Upvotes: 4
Views: 3221
Reputation: 1763
The following code snippet comes from this comment that I found to be very helpful.
gulp.task('strings', function() {
return gulp.src('media/templates/*.jade')
.pipe(foreach(function(stream,file){
var filename = path.basename(file.path);
filename = filename.split('.')[0]
return stream
.pipe(jade({
client: true,
name: filename
}));
}))
.pipe(concat('all.js'))
.pipe(gulp.dest('media/strings/'))
});
Using gulp-foreach you can get the current file's name, change it, and then pass it on to jade. After that you can perform other actions, like concat
, as normal.
Upvotes: 3
Reputation: 21
I found an elegant solution that works for me.
Basically, in your main script (the one you load BEFORE the jade generated scripts in your .html file), you have an array that will hold the returned values of the template() functions, say var document = [];
You then use gulp-insert
to wrap to the scripts '(function() {'
and ;\n;document.push(template()); })();
, then concatenate those scripts as you have already done.
Now pop the document[]
array as you need, with the computed values from each template()
call inside!
I use LiveScript for my build, but here is a converted JavaScript version:
var jade = require('gulp-jade');
var concat = require('gulp-concat');
var insert = require('gulp-insert');
gulp.task('jade-to-js', function(){
return gulp.src('src/node/jade/*.jade')
.pipe(jade({client: true}))
.pipe(insert.wrap('(function() {', '\n;document.push(template()); })();')
.pipe(concat('bundle.js'))
.pipe(gulp.dest('src/js/'))
});
Upvotes: 2
Reputation: 4777
It seems that jade.compileClient
hard-codes function template(locals)
and it has no option to change the function name. https://github.com/visionmedia/jade/blob/master/lib/jade.js
This is a bit hacky but you can modify the contents of the compiled scripts after the jade compilation.
var through = require('through2');
var path = require('path');
function modify() {
function transform(file, enc, callback) {
if (!file.isBuffer()) {
this.push(file);
callback();
return;
}
var funcName = path.basename(file.path, '.js');
var from = 'function template(locals) {';
var to = 'function ' + funcName + '(locals) {';
var contents = file.contents.toString().replace(from, to);
file.contents = new Buffer(contents);
this.push(file);
callback();
}
return through.obj(transform);
}
gulp.src("templates/**/*.jade")
.pipe(jade({client: true}))
.pipe(modify())
.pipe(concat("templates.js"))
.pipe(gulp.dest("../website/templates"));
You can change the funcName
as you like based on file.path
if your jade templates are in multiple subdirectories.
Upvotes: 8