Site Logo

Pixel-in-Gene

Exploring Frontend Development with Design / Graphics / Technology

Consuming Browserify bundles with Webpack

If you are only using Browserify or only Webpack in your project, you don’t have to worry about consuming external bundles. Either of them will take care of it for you. However if you are in a situation like mine where you have legacy code in the application, bundled by Browserify and newer shiny code bundled with Webpack, then this post is all for you!

In Short: We will consume the Browserify-bundled code as externals within Webpack.

browserify webpack

How do we do it?

Now the general idea we are going for is to treat the browserify-bundles as externals to our Webpack build. If you read the documentation for externals, it has options like

  • string
  • object
  • function: function(context, request, callback)
  • RegExp
  • array

which tell you how your external bundle should be resolved at runtime.

In my case, the function-based option was exactly what I needed.

function(context, request, callback) {
    /* ... */
}

With a function, you get to decide how the request should be resolved. For the other types of externals, Webpack will look at the value for output.libraryTarget.

output.libraryTarget has a bunch of different options like:

  • var
  • this
  • commonjs
  • amd
  • umd

After some trial and error, commonjs appeared like the right value. But … in vain. It resulted in a runtime error:

Uncaught ReferenceError: exports is not defined

function-based external was my only remaining hope.

function-based external

Since Browserify provides CommonJS-style behavior on the browser, it also shims a handy utility: the require function, on the window object. Luckily, this is our savior when trying to load browserify-bundles with Webpack.

If we go with the function-based approach to resolving the external, we will end up with a function like so.

const BROWSERIFY_BUNDLE_PATTERN = /core|services|helpers|(^.*\.bundle)/;
function(context, request, callback) {
    if (BROWSERIFY_BUNDLE_PATTERN.test(request)) {
        return callback(null, `require('${request}')`);
    }

    callback();
}

Since we know that browserify will put the require function on window, we can use that to do the resolution of the bundle (aka request) at runtime. Note how I am passing the require statement in the callback(). If the request matches the known set of bundle patterns, we will resolve them with the require statement.

In the webpack-generated bundle, we will see some lines like so:

// ...

function(module, exports) {
    module.exports = require('hello.bundle');
}

// ...

where hello.bundle is an external browserify-bundle.

And that’s how we consume browserify bundles with webpack!

Consuming Browserify bundles with Webpack
Pavan Podila
Pavan Podila
July 11th, 2016