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.
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
function(context, request, callback)
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 externalSince 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!