pete
pete

Reputation: 2799

How to require Underscore templates with Browserify + Gulp

I'm setting up a Backbone project with Browserify & Gulp and can't seem to figure out how to require Underscore templates (not Handlebars) in my modules. The closest I've come is using "node-underscorify" (at least seeing something and no errors), but it's not quite right..

gulpfile.js

var gulp       = require('gulp');
var browserify = require('browserify');
var source     = require('vinyl-source-stream');
var buffer     = require('vinyl-buffer');
var uglify     = require('gulp-uglify');
var gulpif     = require('gulp-if');
var sass       = require('gulp-sass');

var env = process.env.NODE_ENV || 'dev';

gulp.task( 'js', function() {

    var bundler = browserify({
        entries:   ['./dev/js/app.js'],
        paths:     ['./templates/'],                                
        transform: ['node-underscorify']
    });

    return bundler
        .bundle()
        .pipe( source( 'bundle.js') )
        .pipe( buffer() )
        .pipe( gulpif( env === 'prod', uglify() ) )
        .pipe( gulp.dest( './js/' ) );
});

home.html

<h3>Hello <%= name %></h3>

HomeView.js (compiled from CoffeeScript via a separate Gulp task)

(function() {
  var $, Backbone, _;
  $ = require('jquery');
  _ = require('underscore');
  Backbone = require('backbone');
  Backbone.$ = $;

  module.exports = Backbone.View.extend({

    template: require('home.html'),

    el: '#content',

    initialize: function() {
      console.log("home initialize");
      this.render();
    },

    render: function() {
      this.$el.html(this.template({
        name: 'Gulp!'
      }));
      return this;
    }

  });

}).call(this);

When I run the app and it hits HomeView, the browser displays what looks like raw JS of the module, including the uncompiled template (?)

module.exports = function(obj){ var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');}; with(obj||{}){ __p+='
Hello '+ ((__t=( name ))==null?'':__t)+ '

\n\n'; } return __p; };

I tried applying the Underscore template function to the required file but that produces a JS error..

template: _.template( require('home.html') ),

Spent multiple hours perusing various blog posts, trying different solutions -- any help is much appreciated!

Upvotes: 1

Views: 2675

Answers (1)

borekwa
borekwa

Reputation: 31

I was having the same problem. I finally got this working by building off of the example gulp recipe, but per Ben's comment, I explicitly call transform() on underscorify, instead of using the transform array.

I also choose to rename the bundled file along the way and output it in the same directory as the source.

Here's what my final working code looks like:

gulpfile.js

gulp = require("gulp");
browserify = require("browserify");
watchify = require("watchify");
underscorify = require("node-underscorify");
rename = require("gulp-rename");
source = require("vinyl-source-stream");  
gutil = require("gulp-util");

mainBundler = watchify(browserify("./js/main.js"));
mainBundler.transform(underscorify.transform());
gulp.task("watchify-main", bundleMain);
mainBundler.on("update", bundleMain);
mainBundler.on("log", gutil.log);

function bundleMain() {
return mainBundler.bundle()
    .on("error", gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source(".js/main.js"))
    .pipe(rename("main-bundle.js"))
    .pipe(gulp.dest("./js/"));
};

home.html

 <h3>Hello <%= name %></h3>

main.js

template = require("./templates/home.html");

module.exports = Backbone.View.extend({
    template : template,

    el: "#content",

    initialize: function() {
        // initialize code
    },

    render: function() {
        // render code
    }
});

Upvotes: 3

Related Questions