-
-
Notifications
You must be signed in to change notification settings - Fork 10.1k
React: Add components.json for dev and build with examples snippets #32682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
67d5780
5efe183
446abe5
ef96eff
2d86537
3738a60
2442574
18aaaf4
50ea146
addd229
4ed3856
a449847
4ce972a
1599fac
1bcd00b
bf9a49a
f2e3ddb
c0df22c
25b197e
18c671e
11ac914
bd91ab6
1e84547
a6f6673
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| import { cp, mkdir } from 'node:fs/promises'; | ||
| import { cp, mkdir, writeFile } from 'node:fs/promises'; | ||
| import { rm } from 'node:fs/promises'; | ||
| import { join, relative, resolve } from 'node:path'; | ||
|
|
||
|
|
@@ -18,6 +18,7 @@ import { global } from '@storybook/global'; | |
| import picocolors from 'picocolors'; | ||
|
|
||
| import { resolvePackageDir } from '../shared/utils/module'; | ||
| import { type ComponentManifestGenerator } from '../types'; | ||
| import { StoryIndexGenerator } from './utils/StoryIndexGenerator'; | ||
| import { buildOrThrow } from './utils/build-or-throw'; | ||
| import { copyAllStaticFilesRelativeToMain } from './utils/copy-all-static-files'; | ||
|
|
@@ -163,6 +164,21 @@ export async function buildStaticStandalone(options: BuildStaticStandaloneOption | |
| initializedStoryIndexGenerator as Promise<StoryIndexGenerator> | ||
| ) | ||
| ); | ||
|
|
||
| if (features?.experimental_componentsManifest) { | ||
| const componentManifestGenerator: ComponentManifestGenerator = await presets.apply( | ||
| 'componentManifestGenerator' | ||
| ); | ||
| const indexGenerator = await initializedStoryIndexGenerator; | ||
| if (componentManifestGenerator && indexGenerator) { | ||
| const manifests = await componentManifestGenerator(indexGenerator); | ||
| await mkdir(join(options.outputDir, 'manifests'), { recursive: true }); | ||
| await writeFile( | ||
| join(options.outputDir, 'manifests', 'components.json'), | ||
| JSON.stringify(manifests) | ||
| ); | ||
| } | ||
| } | ||
|
Comment on lines
+167
to
+181
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for manifest generation. The manifest generation and file write operations have no error handling. If any step fails, it will crash the entire build process. Consider wrapping this block in a try-catch to log errors gracefully without breaking the build. Apply this diff: if (features?.experimental_componentsManifest) {
- const componentManifestGenerator: ComponentManifestGenerator = await presets.apply(
- 'componentManifestGenerator'
- );
- const indexGenerator = await initializedStoryIndexGenerator;
- if (componentManifestGenerator && indexGenerator) {
- const manifests = await componentManifestGenerator(indexGenerator);
- const manifestsDir = join(options.outputDir, 'manifests');
- await mkdir(manifestsDir, { recursive: true });
- await writeFile(
- join(manifestsDir, 'components.json'),
- JSON.stringify(manifests)
- );
+ try {
+ const componentManifestGenerator: ComponentManifestGenerator = await presets.apply(
+ 'componentManifestGenerator'
+ );
+ const indexGenerator = await initializedStoryIndexGenerator;
+ if (componentManifestGenerator && indexGenerator) {
+ const manifests = await componentManifestGenerator(indexGenerator);
+ const manifestsDir = join(options.outputDir, 'manifests');
+ await mkdir(manifestsDir, { recursive: true });
+ await writeFile(
+ join(manifestsDir, 'components.json'),
+ JSON.stringify(manifests)
+ );
+ }
+ } catch (error) {
+ logger.warn('Failed to generate component manifests:', error);
}
}
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| if (!core?.disableProjectJson) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,6 +8,7 @@ import polka from 'polka'; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import invariant from 'tiny-invariant'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { telemetry } from '../telemetry'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { type ComponentManifestGenerator } from '../types'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { StoryIndexGenerator } from './utils/StoryIndexGenerator'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { doTelemetry } from './utils/doTelemetry'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { getManagerBuilder, getPreviewBuilder } from './utils/get-builders'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -135,6 +136,31 @@ export async function storybookDevServer(options: Options) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw indexError; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const features = await options.presets.apply('features'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (features?.experimental_componentsManifest) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| app.use('/manifests/components.json', async (req, res) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const componentManifestGenerator: ComponentManifestGenerator = await options.presets.apply( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'componentManifestGenerator' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const indexGenerator = await initializedStoryIndexGenerator; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (componentManifestGenerator && indexGenerator) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const manifest = await componentManifestGenerator(indexGenerator); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res.setHeader('Content-Type', 'application/json'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res.end(JSON.stringify(manifest)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res.statusCode = 400; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res.end('No component manifest generator configured.'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.error(e instanceof Error ? e : String(e)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res.statusCode = 500; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| res.end(e instanceof Error ? e.toString() : String(e)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+141
to
+163
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure consistent JSON response format and appropriate status codes. The endpoint has good error handling, but there are inconsistencies:
Apply this diff to improve consistency and clarity: - res.statusCode = 400;
- res.end('No component manifest generator configured.');
+ res.statusCode = 500;
+ res.setHeader('Content-Type', 'application/json');
+ res.end(JSON.stringify({ error: 'No component manifest generator configured.' }));
return;
} catch (e) {
- logger.error(e instanceof Error ? e : String(e));
+ logger.error('Failed to generate component manifest:', e instanceof Error ? e : String(e));
res.statusCode = 500;
- res.end(e instanceof Error ? e.toString() : String(e));
+ res.setHeader('Content-Type', 'application/json');
+ res.end(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }));
return;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Now the preview has successfully started, we can count this as a 'dev' event. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| doTelemetry(app, core, initializedStoryIndexGenerator, options); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.