rendrjs / rendr

Render your Backbone.js apps on the client and the server, using Node.js.
MIT License
4.09k stars 312 forks source link

Gulp #306

Closed ghost closed 10 years ago

ghost commented 10 years ago

Maybe have a look to Gulp (http://gulpjs.com/) for the build tool.

lo1tuma commented 10 years ago

Rendr itself doesn’t use any build tool.

For our app I've tried to switch to gulp. It does work with a lot of workarounds because gulp-browserify and gulp-handlebars doesn’t work the same as grunt-browserify and grunt-handlebars. gulp-handlebars isn’t able to create a single file (compiledTemplats.js), instead each template compiles to single file. gulp-browserify doesn’t support aliasMappings and requires you to specify a single file as entry point and not a whole directory.

I hope we can get rid of those workarounds soon, but we have do make a few changes to rendr. #242 would partially solve the problem with aliasMappings

ghost commented 10 years ago

Ok thanks for that precision.

Maybe for gulp-handlebars you can do that:

gulp.task('templates', function(){
  gulp.src(['client/templates/*.hbs'])
    .pipe(handlebars())
    .pipe(concat('templates.js'))
    .pipe(gulp.dest('build/js/'));
});
lo1tuma commented 10 years ago

That will not work because each compiled template is a CommonJS module, so you would end up with multiple module.exports = in the concatenated file.

ghost commented 10 years ago

Ok I see, which is a shame.

alexindigo commented 10 years ago

You can have more than one target for the templates build.

This is our build setup:

  compile_server: {
    options: {
      namespace: false,
      commonjs: true,
      processName: function(filename) {
        return filename.replace('app/templates/', '').replace('.hbs', '');
      }
    },
    src: "app/templates/**/*.hbs",
    dest: "app/templates/compiledTemplates.js",
    filter: function(filepath) {
      var filename = path.basename(filepath);
      // Exclude files that begin with '__' from being sent to the client,
      // i.e. __layout.hbs.
      return filename.slice(0, 2) !== '__';
    }
  },

  compile_client: {
    options: {
      amd: true,
      processName: function(filename) {
        return filename.replace('app/templates/', '').replace('.hbs', '');
      }
    },
    src: "app/templates/**/*.hbs",
    dest: "public/js/app/templates/compiledTemplates.js",
    filter: function(filepath) {
      var filename = path.basename(filepath);
      // Exclude files that begin with '__' from being sent to the client,
      // i.e. __layout.hbs.
      return filename.slice(0, 2) !== '__';
    }
  }

As you see we compile one file for server side use, CommonJS style and another one for client side use, AMD style, since it builds from the same source of truth we're not worrying about discrepancies.

lo1tuma commented 10 years ago

This looks like grunt. gulp-handlebars does not compile to a single file like compiledTemplates.js no matter what modul system you configure. You can specify an output folder where you will get one compiled file per template.

alexindigo commented 10 years ago

Oh, I misread the problem. I have itchy finger for CommonJS, almost like Pavlov's dog. :)

c089 commented 10 years ago

It would be cool to remove the problems that prevent from using gulp (or any other tool) for the buildin the future (e.g. I've never liked the single-file, hardcoded place compiledTemplates).

BerkeleyTrue commented 10 years ago

In case anyone is still trying to make gulp work to compile your templates, this seems to be working for me.

gulp.task('templates', function() {
    gulp.src(['app/templates/**/[!__]*.hbs'])
      .pipe(handlebars())
      .pipe(wrap('templates["<%= file.relative %>"] = <%= file.contents %>;     \n'))
      .pipe(concat('compiledTemplates.js'))
      .pipe(wrap('module.exports = function(Handlebars){\ntemplates = {};\n<    %= contents %>\nreturn templates \n};'))
      .pipe(gulp.dest('app/templates/'));
  });

I am, however, still trying to figure out gulp and browserify.

dettier commented 10 years ago

I managed to get gulp create my browserify bundle. I had to use node-browserify, as gulp-broswerify plugin doesn’t support aliasMappings as was mentioned earlier. Watchify works too as well, and it substantially cuts time creating bundle when gulp watching for files.

If anyone is interested I can try to create pull request with gulp example or provide some code here.

BerkeleyTrue commented 10 years ago

I would like to see how you got that working. I got it to work on my end but with a lot of errors, a bloated bundle, and not in a gulpy-way.

dettier commented 10 years ago

I just added PR with gulp example (https://github.com/rendrjs/rendr/pull/352). It's definitely not the gulpiest-way possible, but you can't do much with current gulp-browserify plugin.