import { Middleware } from 'koa'; import koaEtag from 'koa-etag'; import { FSWatcher } from 'chokidar'; import { DevServerCoreConfig } from './DevServerCoreConfig'; import { basePathMiddleware } from '../middleware/basePathMiddleware'; import { etagCacheMiddleware } from '../middleware/etagCacheMiddleware'; import { historyApiFallbackMiddleware } from '../middleware/historyApiFallbackMiddleware'; import { pluginMimeTypeMiddleware } from '../middleware/pluginMimeTypeMiddleware'; import { pluginServeMiddleware } from '../middleware/pluginServeMiddleware'; import { pluginTransformMiddleware } from '../middleware/pluginTransformMiddleware'; import { Logger } from '../logger/Logger'; import { watchServedFilesMiddleware } from '../middleware/watchServedFilesMiddleware'; import { pluginFileParsedMiddleware } from '../middleware/pluginFileParsedMiddleware'; import { serveFilesMiddleware } from '../middleware/serveFilesMiddleware'; /** * Creates middlewares based on the given configuration. The middlewares can be * used by a koa server using `app.use()`: */ export function createMiddleware( config: DevServerCoreConfig, logger: Logger, fileWatcher: FSWatcher, ) { const middlewares: Middleware[] = []; middlewares.push(async (ctx, next) => { logger.debug(`Receiving request: ${ctx.url}`); await next(); logger.debug(`Responding to request: ${ctx.url} with status ${ctx.status}`); }); // strips a base path from requests if (config.basePath) { middlewares.push(basePathMiddleware(config.basePath)); } // adds custom user's middlewares for (const m of config.middleware ?? []) { middlewares.push(m); } // watch files that are served middlewares.push(watchServedFilesMiddleware(fileWatcher, config.rootDir)); // serves 304 responses if resource hasn't changed middlewares.push(etagCacheMiddleware()); // adds etag headers for caching middlewares.push(koaEtag()); // serves index.html for non-file requests for SPA routing if (config.appIndex) { middlewares.push(historyApiFallbackMiddleware(config.appIndex, config.rootDir, logger)); } const plugins = config.plugins ?? []; middlewares.push(pluginFileParsedMiddleware(plugins)); middlewares.push(pluginTransformMiddleware(logger, config, fileWatcher)); middlewares.push(pluginMimeTypeMiddleware(logger, plugins)); middlewares.push(pluginServeMiddleware(logger, plugins)); middlewares.push(...serveFilesMiddleware(config.rootDir)); return middlewares; }