Question

I am trying to browserify a Rendr application. I have tried multiple ways with no success.

Here is one version that I have tried using Gulp-browserify(Now deprecated in favor of plain browserify).

gulp.task('browserify-gulp', function() {
    gulp.src(['app/**/*.js'])
    .pipe(gulpbrowserify())
    .pipe(concat('mergedGulp.js'))
    .pipe(gulp.dest('public/'));
  });

And this errors out

Error: module "app/router" not found from rendr_project/node_modules/rendr/shared/app.js"

Here is a different approach using stock Browserify and vinyl-source-stream. This gives me the same error.

gulp.task('browserify', function() {
  var bundle = browserify( './app/app.js' ).bundle();
  return bundle.pipe(source( 'mergedAssets.js' )).pipe(gulp.dest('public/'));
});

The line in .../shared/app.js that cause this behavior is

if (!isServer) {
  ClientRouter = require('app/router');// <---here
  Backbone.$ = window.$ || require('jquery');
}

Any guidance would be greatly appreciated.

For reference, here is the same task using Grunt and Grunt-Browserify.

browserify: {
    options: {
      debug: true,
      alias: [
        'node_modules/rendr-handlebars/index.js:rendr-handlebars'
      ],
      aliasMappings: [
        {
          cwd: 'app/',
          src: ['**/*.js'],
          dest: 'app/'
        }
      ],
      shim: {
        jquery: {
          path: 'assets/vendor/jquery.js',
          exports: '$'
        }
      }
    },
    app: {
      src: [ 'app/**/*.js' ],
      dest: 'public/mergedAssets.js'
    }
  }
});

This works great, but I would like to move everything over to gulp which seems much more intuitive.

EDIT:

I have found a work around using gulp-browserify.

gulp.src(['app/**/*.js'])
  .pipe(browserify({
    insertGlobals: true,
    debug: !gulp.env.production
  }).on('prebundle', function(bundler) {
    bundler.require( __dirname + '/app/router', {expose: 'app/router'} );
    bundler.require( __dirname + '/app/views/base', {expose: '../base'});
  }))
  .pipe(concat('mergedAssets.js'))
  .pipe(gulp.dest('public/'));

This compiles and the app seems to be working, but the file output seems to have ballooned to over 8 mb while the file compiled with grunt-browserify is steady at 1.5mb. I also see errors in the browsers console where certain modules are not being found. Another downside it gulp-browserify being blacklisted. And it seems that browserify does not have support for the 'prebundle' event.

You can also see that I have to require two files in my app. Currently there are a total of 6 files. I imagine as the app becomes complex I will have to manually require more files.

AliasMapping is indeed a much needed feature of Browserify. Hopefully someone knows a way to get this working using just Browserify.

Was it helpful?

Solution

Alright, looks like someone figured it out for me. As you can see below, its not very friendly or Gulpy. Looks like a someone needs to make a bundler specifically for Gulp because this is horrible to look at.

It spits out the same size file as grunt-browserify does. So thats a pass.

var rendrClientFiles = glob.sync('rendr/{client,shared}/**/*.js', { cwd : './node_modules/' });
var rendrModules = rendrClientFiles.map(function (file) {
  return file.replace('.js', '')
});

/**
 * Bundle SquidInk app
 * @param globs
 * @returns {*}
 */
var getBundler = function (globs) {

  var bundler, files;

  bundler = browserify({
    fullPaths : false,
    entries   : []
  });

  globs.forEach(function (pattern) {
    files = glob.sync(pattern, { cwd : './' });
    files.forEach(function (file) {
      // it's nesessary for some app modules (e.g. 'app/app')
      // to be exposed otherwise rendr couldn't require them
      var moduleName = file.replace(/.js$/, '');
      bundler.require('./' + file, { expose: moduleName});
    });
  });

  rendrModules.forEach(function (moduleName) {
    bundler.require(moduleName);
  });

  bundler.require('rendr-handlebars');
  bundler.require('jquery');

  return bundler;
};

gulp.task('browserify:app', function() {
  var bundler = getBundler([ 'app/**/*.js' ]),
    options = { insertGlobals : false, debug : true };

  return bundler.bundle(options)
    .pipe(plumberPlus())
    .pipe(source('mergedAssets.js'))
    .pipe(gulp.dest('./public'));
});

Credits: https://github.com/dettier/rendr/blob/4f2c96b8233830430eee5841b34a9f9cd47e9a34/examples/07_gulp/gulpfile.js

OTHER TIPS

I am actually having the same issue right now. the problem is in the missing aliasMapping in gulp-browserify and node-browserify. checkout https://github.com/deepak1556/gulp-browserify/issues/46 I am trying to find a way around it using shortify but keep getting errors about missing modules from inside rendr like missing "rendr/shared/app/". hope this might get the brain storming going.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top