Compile client-side Jade templates using Gulpjs

别来无恙 提交于 2019-12-07 09:40:07

问题


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


回答1:


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.




回答2:


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.




回答3:


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/'))
});


来源:https://stackoverflow.com/questions/22234869/compile-client-side-jade-templates-using-gulpjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!