From 844d6d2e8c394afc8a78942d9c9764a82b9ee22c Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Sat, 11 Mar 2023 16:09:22 +0800 Subject: [PATCH] refactor(core,cloud): disable cache for index files --- packages/cloud/src/middleware/with-spa.ts | 14 ++++++++++++-- packages/core/src/middleware/koa-serve-static.ts | 13 +++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/cloud/src/middleware/with-spa.ts b/packages/cloud/src/middleware/with-spa.ts index 267bed713..0c52f3f17 100644 --- a/packages/cloud/src/middleware/with-spa.ts +++ b/packages/cloud/src/middleware/with-spa.ts @@ -30,6 +30,11 @@ export type WithSpaConfig = { * @default 'index.html' */ indexPath?: string; + /** + * Explicitly disable cache for the index file in order to keep fresh and avoid cache invalidation issues. + * @default true + */ + disableIndexCache?: boolean; }; export default function withSpa({ @@ -38,6 +43,7 @@ export default function withSpa({ pathname: rootPathname = '/', ignorePathnames, indexPath: index = 'index.html', + disableIndexCache = true, }: WithSpaConfig) { assert(root, new Error('Root directory is required to serve files.')); @@ -69,6 +75,7 @@ export default function withSpa({ return next({ ...context, status: 404 }); } + const [originalPath] = result; const [pathLike, stat, compression] = (await tryCompressedFile(request, result[0])) ?? result; return next({ @@ -77,9 +84,12 @@ export default function withSpa({ ...headers, ...(compression && { 'Content-Encoding': compression }), ...(!compression && { 'Content-Length': stat.size }), - 'Content-Type': mime.lookup(result[0]), // Use the original path to lookup + 'Content-Type': mime.lookup(originalPath), 'Last-Modified': stat.mtime.toUTCString(), - 'Cache-Control': `max-age=${maxAge}`, + 'Cache-Control': + disableIndexCache && originalPath === indexPath + ? 'no-cache, no-store, must-revalidate' + : `max-age=${maxAge}`, ETag: `"${stat.size.toString(16)}-${stat.mtimeMs.toString(16)}"`, }, stream: createReadStream(pathLike), diff --git a/packages/core/src/middleware/koa-serve-static.ts b/packages/core/src/middleware/koa-serve-static.ts index 01d498658..7987a02b9 100644 --- a/packages/core/src/middleware/koa-serve-static.ts +++ b/packages/core/src/middleware/koa-serve-static.ts @@ -7,23 +7,32 @@ import send from 'koa-send'; import assertThat from '#src/utils/assert-that.js'; +const index = 'index.html'; + export default function serve(root: string) { assertThat(root, new Error('Root directory is required to serve files.')); const options: send.SendOptions = { root: path.resolve(root), - index: 'index.html', + index, }; const serve: MiddlewareType = async (ctx, next) => { if (ctx.method === 'HEAD' || ctx.method === 'GET') { - await send(ctx, ctx.path, { + const filePath = await send(ctx, ctx.path, { ...options, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing ...(!['/', `/${options.index || ''}`].some((path) => ctx.path.endsWith(path)) && { maxage: 604_800_000 /* 7 days */, }), }); + + const filename = path.basename(filePath); + + // No cache for the index file + if (filename === index || filename.startsWith(index + '.')) { + ctx.set('Cache-Control', 'no-cache, no-store, must-revalidate'); + } } return next();