[cli][dev][node] Support matchers config for Middleware in vc dev (#8033)

Adds support for `config.matchers` exported property in Middleware during `vc dev`.
This commit is contained in:
Nathan Rajlich
2022-06-28 01:34:48 -07:00
committed by GitHub
parent e42fe34c4a
commit 0e35205bf1
4 changed files with 52 additions and 1 deletions

View File

@@ -1430,6 +1430,7 @@ export default class DevServer {
meta: {
isDev: true,
devCacheDir,
requestUrl: req.url,
env: { ...envConfigs.runEnv },
buildEnv: { ...envConfigs.buildEnv },
},

View File

@@ -0,0 +1,13 @@
// Supports both a single string value or an array of matchers
export const config = {
matcher: ['/about/:path*', '/dashboard/:path*'],
};
export default function middleware(request, _event) {
const response = new Response('middleware response');
// Set custom header
response.headers.set('x-modified-edge', 'true');
return response;
}

View File

@@ -505,3 +505,21 @@ test(
await testPath(500, '/', /EDGE_FUNCTION_INVOCATION_FAILED/);
})
);
test(
'[vercel dev] Middleware with `matchers` config',
testFixtureStdio(
'middleware-matchers',
async (testPath: any) => {
// TODO: remove once latest `@vercel/node` is shipped to stable with `matchers` support (fails because `directoryListing`)
//await testPath(404, '/');
await testPath(404, '/another');
await testPath(200, '/about/page', 'middleware response');
await testPath(200, '/dashboard/home', 'middleware response');
},
{
// TODO: remove once latest `@vercel/node` is shipped to stable with `matchers` support
skipDeploy: true,
}
)
);

View File

@@ -460,7 +460,26 @@ export const prepareCache: PrepareCache = ({ repoRootPath, workPath }) => {
export const startDevServer: StartDevServer = async opts => {
const { entrypoint, workPath, config, meta = {} } = opts;
const entryDir = join(workPath, dirname(entrypoint));
const entrypointPath = join(workPath, entrypoint);
if (config.middleware === true && typeof meta.requestUrl === 'string') {
// TODO: static config is also parsed in `dev-server.ts`.
// we should pass in this version as an env var instead.
const project = new Project();
const staticConfig = getConfig(project, entrypointPath);
// Middleware is a catch-all for all paths unless a `matcher` property is defined
const matchers = new RegExp(getRegExpFromMatchers(staticConfig?.matcher));
if (!matchers.test(meta.requestUrl)) {
// If the "matchers" doesn't say to handle this
// path then skip middleware invocation
return null;
}
}
const entryDir = dirname(entrypointPath);
const projectTsConfig = await walkParentDirs({
base: workPath,
start: entryDir,