Skip to content

Commit 6de6c57

Browse files
Merge pull request #30567 from storybookjs/valentin/fix-runtime-iframe-error-on-first-load
Builder-Vite: Fix runtime and iframe 404 on first load
2 parents e5f5bf5 + b7126ab commit 6de6c57

File tree

5 files changed

+11
-36
lines changed

5 files changed

+11
-36
lines changed

code/builders/builder-vite/src/codegen-modern-iframe-script.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { Options, PreviewAnnotation } from 'storybook/internal/types';
44
import { dedent } from 'ts-dedent';
55

66
import { processPreviewAnnotation } from './utils/process-preview-annotation';
7-
import { SB_VIRTUAL_FILES, getResolvedVirtualModuleId } from './virtual-file-names';
7+
import { SB_VIRTUAL_FILES } from './virtual-file-names';
88

99
export async function generateModernIframeScriptCode(options: Options, projectRoot: string) {
1010
const { presets, configDir } = options;

code/builders/builder-vite/src/index.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type { Middleware, Options } from 'storybook/internal/types';
77
import type { ViteDevServer } from 'vite';
88

99
import { build as viteBuild } from './build';
10-
import { transformIframeHtml } from './transform-iframe-html';
1110
import type { ViteBuilder } from './types';
1211
import { createViteServer } from './vite-server';
1312

@@ -16,22 +15,8 @@ export { hasVitePlugins } from './utils/has-vite-plugins';
1615

1716
export * from './types';
1817

19-
function iframeMiddleware(options: Options, server: ViteDevServer): Middleware {
20-
return async (req, res, next) => {
21-
if (!req.url || !req.url.match(/^\/iframe\.html($|\?)/)) {
22-
next();
23-
return;
24-
}
25-
// the base isn't used for anything, but it's required by the URL constructor
26-
const url = new URL(req.url, 'http://localhost:6006');
27-
28-
// We need to handle `html-proxy` params for style tag HMR https://github.com/storybookjs/builder-vite/issues/266#issuecomment-1055677865
29-
// e.g. /iframe.html?html-proxy&index=0.css
30-
if (url.searchParams.has('html-proxy')) {
31-
next();
32-
return;
33-
}
34-
18+
function iframeHandler(options: Options, server: ViteDevServer): Middleware {
19+
return async (req, res) => {
3520
const indexHtml = await readFile(require.resolve('@storybook/builder-vite/input/iframe.html'), {
3621
encoding: 'utf8',
3722
});
@@ -57,7 +42,7 @@ export const start: ViteBuilder['start'] = async ({
5742
}) => {
5843
server = await createViteServer(options as Options, devServer);
5944

60-
router.use(iframeMiddleware(options as Options, server));
45+
router.get('/iframe.html', iframeHandler(options as Options, server));
6146
router.use(server.middlewares);
6247

6348
return {

code/builders/builder-vite/src/optimizeDeps.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const INCLUDE_CANDIDATES = [
2727
'@storybook/addon-essentials/outline/preview',
2828
'@storybook/addon-essentials/viewport/preview',
2929
'@storybook/addon-highlight/preview',
30+
'@storybook/addon-interactions/preview',
3031
'@storybook/addon-links/preview',
3132
'@storybook/addon-measure/preview',
3233
'@storybook/addon-outline/preview',
@@ -132,6 +133,7 @@ const INCLUDE_CANDIDATES = [
132133
'react-textarea-autosize',
133134
'react',
134135
'react/jsx-runtime',
136+
'react/jsx-dev-runtime',
135137
'refractor/core',
136138
'refractor/lang/bash.js',
137139
'refractor/lang/css.js',
@@ -150,6 +152,7 @@ const INCLUDE_CANDIDATES = [
150152
'slash',
151153
'store2',
152154
'storybook/internal/preview/runtime',
155+
'storybook/internal/csf',
153156
'synchronous-promise',
154157
'telejson',
155158
'ts-dedent',

code/core/assets/server/template.ejs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,5 @@
8383
8484
import './sb-manager/runtime.js';
8585
</script>
86-
87-
<% if (!ignorePreview) { %>
88-
<link href="./sb-preview/runtime.js" rel="prefetch" as="script" />
89-
<% } %>
9086
</body>
91-
</html>
87+
</html>

code/core/src/core-server/dev-server.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,14 @@ export async function storybookDevServer(options: Options) {
7878
channel: serverChannel,
7979
});
8080

81-
let previewStarted: Promise<any> = Promise.resolve();
81+
let previewResult: Awaited<ReturnType<(typeof previewBuilder)['start']>> =
82+
await Promise.resolve();
8283

8384
if (!options.ignorePreview) {
8485
if (!options.quiet) {
8586
logger.info('=> Starting preview..');
8687
}
87-
previewStarted = previewBuilder
88+
previewResult = await previewBuilder
8889
.start({
8990
startTime: process.hrtime(),
9091
options,
@@ -108,14 +109,6 @@ export async function storybookDevServer(options: Options) {
108109
});
109110
}
110111

111-
// this is a preview route, the builder has to be started before we can serve it
112-
// this handler keeps request to that route pending until the builder is ready to serve it, preventing a 404
113-
app.use('/iframe.html', (req, res, next) => {
114-
// We need to catch here or node will treat any errors thrown by `previewStarted` as
115-
// unhandled and exit (even though they are very much handled below)
116-
previewStarted.catch(() => {}).then(() => next());
117-
});
118-
119112
const listening = new Promise<void>((resolve, reject) => {
120113
server.once('error', reject);
121114
app.listen({ port, host }, resolve);
@@ -132,8 +125,6 @@ export async function storybookDevServer(options: Options) {
132125
throw indexError;
133126
}
134127

135-
const previewResult = await previewStarted;
136-
137128
// Now the preview has successfully started, we can count this as a 'dev' event.
138129
doTelemetry(app, core, initializedStoryIndexGenerator, options);
139130

0 commit comments

Comments
 (0)