Vendor Bundle to Improve Gulp Build Speed

Since the previous post I’ve looked more into Gulp. I started migrating the tool website from the Express/React setup to use the static-react-starter project starter. The transition has worked fine so far, but I’ve realized some issues with the starter project.

The build time quickly became annoying. To fix this, I tried replacing gulp.watch with watchify for the JS files. Watchify helps incrementally rebuilding your bundles while developing, and works together with browserify. This really helped speed up the script rebundling time. Before it could take anywhere from 5-10 seconds from saving a file to the update appeared in the browser. After the switch, it takes less than a second. However, the initial build time only improved marginally, if at all. After adding uglify to the script task, the initial build time was around 14 seconds.


Creating an External Vendor Bundle

What solved this problem for me, was creating a vendor script bundle in addition to each subpage’s app script bundle. This can be done by taking Browserify’s external and require options in use. The result was that each app script bundle would only take around 1 second to build, whereas the vendor script bundle takes around 5 seconds to build. Much faster!


Why you Should do This


Vendor Bundle with Gulp Recipe

Import Project Dependencies

Start by loading the dependencies into your Gulp file:

...
import packageJson from './package.json';

const dependencies = Object.keys(packageJson.dependencies || {});
...

The dependencies variable will contain a list of your project dependencies that you’ve added through npm install <dep> --save.

Modify your Script Bundler Gulp Task

You will need to tell Browserify about external requires. When Browserify encounters a require (or import) marked as external it will ignore it when building a bundle. Basically, it will trust you to add these dependencies through another script tag somewhere in your HTML.

...

let b = browserify(opts);
b.external(dependencies);
b.transform(babelify);

...

Create a Vendor Bundling Gulp Task

After modifying the app bundling task to ignore the dependencies, you’ll need to create a vendor script file. Create a new Gulp task:

export function vendorScripts() {
  return browserify()
  .require(dependencies)
  .bundle()
  .on('error', (err) => console.log(err))
  .pipe(source('vendor.js'))
  .pipe(buffer())
  .pipe(uglify({compress: {unused: false}}))
  .pipe(gulp.dest(dirs.dest + '/app'))
}

You will also have to include this new task in your build task:

...

const build = gulp.series(clean, gulp.parallel(styles, vendorScripts, scripts, images, sounds, views))
export { build }

...

Add new Script Tag

Somewhere in your HTML, above where the app bundle script is, include the vendor bundle script. For instance:

...

<script src="/app/vendor.js"></script>
<script src="/app/tool1/entry.bundle.js"></script>

...

If you go to Chrome’s Network tab in the inspect window, you can see both vendor.js and entry.bundle.js will be requested on page load.

To see the entire Gulp file, go here.