Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 30a5263

Browse files
authored
Merge pull request #30467 from storybookjs/jeppe/staticdirs-workaround
Core: Fix statically serving single files and multiple dirs on the same endpoint
2 parents 02baa78 + e82077b commit 30a5263

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

code/core/src/core-server/utils/server-statics.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { existsSync } from 'node:fs';
1+
import { existsSync, statSync } from 'node:fs';
22
import { basename, isAbsolute, posix, resolve, sep, win32 } from 'node:path';
33

44
import { getDirectoryFromWorkingDir } from '@storybook/core/common';
@@ -26,9 +26,25 @@ export async function useStatics(app: Polka.Polka, options: Options): Promise<vo
2626
);
2727
}
2828

29+
if (existsSync(staticPath) && statSync(staticPath).isFile()) {
30+
// sirv doesn't support serving single files, so we need to pass the file's directory to sirv instead
31+
const staticPathDir = resolve(staticPath, '..');
32+
const staticPathFile = basename(staticPath);
33+
app.use(targetEndpoint, (req, res, next) => {
34+
// Rewrite the URL to match the file's name, ensuring that we only ever serve the file
35+
// even when sirv is passed the full directory
36+
req.url = `/${staticPathFile}`;
37+
sirvWorkaround(staticPathDir, {
38+
dev: true,
39+
etag: true,
40+
extensions: [],
41+
})(req, res, next);
42+
});
43+
return;
44+
}
2945
app.use(
3046
targetEndpoint,
31-
sirv(staticPath, {
47+
sirvWorkaround(staticPath, {
3248
dev: true,
3349
etag: true,
3450
extensions: [],
@@ -43,14 +59,38 @@ export async function useStatics(app: Polka.Polka, options: Options): Promise<vo
4359

4460
app.get(
4561
`/${basename(faviconPath)}`,
46-
sirv(faviconPath, {
62+
sirvWorkaround(faviconPath, {
4763
dev: true,
4864
etag: true,
4965
extensions: [],
5066
})
5167
);
5268
}
5369

70+
/**
71+
* This is a workaround for sirv breaking when serving multiple directories on the same endpoint.
72+
*
73+
* @see https://github.com/lukeed/polka/issues/218
74+
*/
75+
const sirvWorkaround: typeof sirv =
76+
(...sirvArgs) =>
77+
(req, res, next) => {
78+
// polka+sirv will modify the request URL, so we need to restore it after sirv is done
79+
// req._parsedUrl is an internal construct used by both polka and sirv
80+
// eslint-disable-next-line no-underscore-dangle
81+
const originalParsedUrl = (req as any)._parsedUrl;
82+
83+
const maybeNext = next
84+
? () => {
85+
// eslint-disable-next-line no-underscore-dangle
86+
(req as any)._parsedUrl = originalParsedUrl;
87+
next();
88+
}
89+
: undefined;
90+
91+
sirv(...sirvArgs)(req, res, maybeNext);
92+
};
93+
5494
export const parseStaticDir = (arg: string) => {
5595
// Split on last index of ':', for Windows compatibility (e.g. 'C:\some\dir:\foo')
5696
const lastColonIndex = arg.lastIndexOf(':');

0 commit comments

Comments
 (0)