Watchify Middleware
watchify-middleware is a lightweight HTTP middleware designed to enhance the development experience when working with Watchify and Browserify. It prevents stale or empty bundles from being served by suspending the server response until the bundle is ready. The middleware, currently at version 1.9.1 (last published in 2017), differentiates itself by removing the default 600ms rebuild delay common in Watchify, offering immediate feedback, and providing an optional browser-based error handler. It exposes timing information via a 'log' event and facilitates seamless integration into Node.js HTTP servers or frameworks like Express, making it ideal for rapid iteration cycles during web development. Its release cadence has been infrequent, with no major updates since its last stable release, positioning it as a mature, maintenance-mode utility.
Common errors
-
Error: Cannot find module 'app.js'
cause The Browserify bundler cannot locate the entry point file specified.fixEnsure that the `app.js` (or your entry file) exists at the path relative to `basedir` provided to Browserify, or specify the full absolute path. -
Error: listen EADDRINUSE: address already in use :::8000
cause The server attempted to listen on a port that is already occupied by another process.fixEither stop the process currently using port 8000 (e.g., kill any lingering Node.js processes) or configure your server to listen on a different, available port. -
Bundle is not updating in the browser after file changes, or updates are very slow.
cause The Browserify instance is likely missing the `cache`, `packageCache` options, or the `watchify` plugin, preventing incremental builds.fixEnsure your `browserify` configuration includes `{ cache: {}, packageCache: {}, plugin: [require('watchify')] }`. -
My server is hanging or not responding when I request the bundle URL.
cause This is often expected behavior if `watchify` is currently rebuilding the bundle. The middleware suspends the response until the bundle is ready.fixCheck the server console for 'log' events from watchify-middleware, indicating if a rebuild is in progress. If the server hangs indefinitely, ensure there are no errors in your `browserify` setup or your application code that are preventing a successful bundle completion.
Warnings
- breaking watchify-middleware explicitly removes the default 600ms debounce delay often present in standard Watchify setups. This means rebuilds will occur immediately upon file changes, which can be a change in behavior if you were relying on that delay.
- gotcha The `errorHandler` option significantly alters how bundle errors are handled. If `errorHandler` is `true` (defaulting to a browser-console error display) or a custom function, the 'error' event on the emitter will *not* be triggered. Errors will be handled internally by the middleware or your custom function.
- gotcha For watchify-middleware to function correctly and efficiently with incremental rebuilds, the underlying Browserify instance *must* be configured with `cache: {}`, `packageCache: {}`, and the `watchify` plugin. Omitting these will result in full rebuilds on every change, negating the performance benefits.
- gotcha watchify-middleware suspends the HTTP response until a fresh bundle is ready. While this prevents serving stale bundles, it means that requests for the bundle URL will appear to 'hang' or take longer during active rebuilds, which might be unexpected behavior for some server monitoring tools or developers.
Install
-
npm install watchify-middleware -
yarn add watchify-middleware -
pnpm add watchify-middleware
Imports
- watchifyMiddleware
import watchifyMiddleware from 'watchify-middleware'
const watchifyMiddleware = require('watchify-middleware') - watchifyMiddleware.emitter
import { emitter } from 'watchify-middleware'const emitter = watchifyMiddleware.emitter(bundler, opt)
- middleware
const middleware = new watchifyMiddleware(bundler)
const middleware = watchifyMiddleware(bundler)
Quickstart
const http = require('http');
const browserify = require('browserify');
const watchifyMiddleware = require('watchify-middleware');
const defaultIndex = require('simple-html-index');
const staticUrl = 'bundle.js';
const appEntry = 'app.js';
// Create a dummy app.js for demonstration
require('fs').writeFileSync(appEntry, 'console.log("Hello from app.js!");');
const bundler = browserify(appEntry, {
cache: {},
packageCache: {},
basedir: __dirname,
plugin: [require('watchify')] // Crucial for watchify integration
});
const watchifyInstance = watchifyMiddleware(bundler, {
errorHandler: true // Use default browser error handler
});
const server = http.createServer(function (req, res) {
if (req.url === '/') {
defaultIndex({ entry: staticUrl }).pipe(res);
} else if (req.url === '/' + staticUrl) {
watchifyInstance(req, res);
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Not Found');
}
});
server.listen(8000, 'localhost', function () {
console.log('Watching and serving http://localhost:8000/');
console.log(`Try changing ${appEntry} and refreshing the browser.`);
});