Middleware Utils
The `middleware-utils` package provides a compact collection of utility functions designed to streamline the creation and management of middleware in Node.js applications. It's particularly useful within build or templating ecosystems, such as `assemble`, where middleware often requires sequential or parallel execution. Key functionalities include `series` and `parallel` for controlling middleware flow, `error` and `handleError` for standardized error reporting, and `delims` for escaping and unescaping template delimiters. The package's current stable version is 1.0.0, originally released in 2017. Due to its age and lack of updates, it effectively has an abandoned release cadence. Its API is callback-based, reflecting the common asynchronous patterns of its era, and it lacks native support for modern JavaScript features like Promises or ES Modules.
Common errors
-
TypeError: (0, _middlewareUtils.series) is not a function
cause Attempting to use ES module named import syntax (`import { series } from 'middleware-utils';`) for a CommonJS package that exports an object, not named functions.fixChange the import statement to `const utils = require('middleware-utils');` and access functions as properties, e.g., `utils.series(...)`. -
Error: Cannot find module 'middleware-utils'
cause The package is not installed in the project's `node_modules` directory, or there's a typo in the import path.fixRun `npm install middleware-utils` or `yarn add middleware-utils` to install the package. Double-check the spelling of the package name in your `require` statement. -
TypeError: next is not a function
cause This error typically occurs within a middleware function when `next` (the callback to proceed to the next middleware) is either not passed correctly or is called after the middleware chain has already completed or encountered an error, leading to an invalid `next` reference.fixEnsure all custom middleware functions passed to `utils.series` or `utils.parallel` properly accept a `next` callback as their last argument and call `next()` exactly once when their asynchronous operations are complete (or `next(err)` if an error occurs).
Warnings
- breaking The `middleware-utils` package is a CommonJS module and does not natively support ES Modules (`import`/`export` syntax). Attempting to use `import` statements directly will likely result in syntax errors or runtime issues in pure ESM environments.
- gotcha This package has not been updated since 2017 (v1.0.0) and is considered abandoned. It targets Node.js `>=4` and uses callback-based asynchronous patterns, which are less common in modern Node.js development that favors Promises and `async`/`await`.
- gotcha The utility functions (`series`, `parallel`, `error`, `handleError`, `delims`) are exposed as properties of the main object returned by `require('middleware-utils')`. They are not individual named exports. Destructuring imports for these functions (`const { series } = require(...)`) will not work as expected and lead to runtime errors.
- deprecated The callback-based API is a dated pattern. Modern Node.js applications heavily utilize Promises and `async`/`await` for asynchronous control flow. Integrating `middleware-utils` into a Promise-based codebase will require wrapping its callback functions in Promises.
Install
-
npm install middleware-utils -
yarn add middleware-utils -
pnpm add middleware-utils
Imports
- utils
const { utils } = require('middleware-utils');import utils from 'middleware-utils';
- series
import { series } from 'middleware-utils';const utils = require('middleware-utils'); const seriesFn = utils.series; - parallel
import { parallel } from 'middleware-utils';const utils = require('middleware-utils'); const parallelFn = utils.parallel;
Quickstart
const utils = require('middleware-utils');
// Simulate an application object that can register middleware
const app = {
_middleware: [],
preRender: function(pattern, fn) {
this._middleware.push({ pattern, fn });
},
// Simple handler to execute middleware
handle: function(view, done) {
const matchingFns = this._middleware.filter(m => view.name.match(m.pattern));
if (matchingFns.length === 0) {
return done(null, view);
}
const seriesRunner = utils.series(matchingFns.map(m => m.fn));
seriesRunner(view, done);
}
};
function createMiddleware(name) {
return function(file, next) {
console.log(`Executing middleware: ${name} for file: ${file.name}`);
// Simulate async work
setTimeout(() => next(), 50);
};
}
// Register middleware using utils.series
app.preRender(/\.hbs$/, utils.series([
createMiddleware('foo'),
createMiddleware('bar'),
createMiddleware('baz')
]));
// Register a single middleware
app.preRender(/\.txt$/, createMiddleware('text-processor'));
console.log('Starting middleware processing...');
app.handle({ name: 'template.hbs', content: '...' }, (err, result) => {
if (err) {
console.error('Error handling .hbs:', err);
} else {
console.log('Finished handling template.hbs.');
}
});
app.handle({ name: 'document.txt', content: '...' }, (err, result) => {
if (err) {
console.error('Error handling .txt:', err);
} else {
console.log('Finished handling document.txt.');
}
});