How to keep Browserify bundle size sensible when using requires for thirdparty stuff (via grunt if it matters)

Pete Duncanson picture Pete Duncanson · Jan 13, 2015 · Viewed 8k times · Source

I'm trying to bundle up my own code (A) which in turn uses 2 third party components (B and C) where C also needs B. Everything as far as I know is written using CommonJS node style modules.

A on its own when bundled comes out at 60K.

B is included separately and assumed to be global, I've got this working just fine by doing a dirty bit of a replace in my build step that swaps out require("B") with global.B

C is whats causing me issues though, its meant to be "just 8K" in size yet when I try bundling it up with A my bundle jumps up to 600K+ as I assume its pulling in dependancies galore?

This is not acceptable but I don't know how to get it any smaller as I don't know what the heck its pulling in (or more importantly what I can exclude to make it still work). I could try a binary chop with the exculsions but I'd don't know if that is a safe way or even sensible way to do it.

How can I bundle C up and only have my bundle come out at 68.5K (total size of both chunks of code 60k + 8.5k) and of course still work?

I'm new to node and browserify but I've been hammering on this for over a week so fair to say I've given it a good stab before putting my hand up.

Additional info if it matters:

  • it needs to run server-side and client-side
  • B is actually ReactJS
  • C is actually React Router Component
  • Using windows and c# via ReactJS.net...hey...wait...come back...tumbleweed

Answer

Jonny Buchanan picture Jonny Buchanan · Jan 13, 2015

If you create an external bundle containing all your app's dependencies (B + C) and declare those modules as external when bundling your app's own code (A), then things should work as you expect.

I don't know the grunt-browserify config incantations for doing this, but the following show how you'd use browserify directly in some example gulp tasks, so the bundle creation should be reusable:

var browserify = require('browserify')
var gulp = require('gulp')
var source = require('vinyl-source-stream')

gulp.task('js-deps', function() {
  var b = browserify()
  b.require('react')
  b.require('react-router-component')
  b.transform('envify')

  return b.bundle()
    .pipe(source('deps.js'))
    .pipe(gulp.dest('./build'))
})

gulp.task('bundle-js', function() {
  var b = browserify('./lib/app.js')
  b.external('react')
  b.external('react-router-component')

  return b.bundle()
    .pipe(source('app.js'))
    .pipe(gulp.dest('./build'))
})