Skip to content

Commit

Permalink
CSF: Forbid duplicate kinds
Browse files Browse the repository at this point in the history
  • Loading branch information
shilman committed Jul 1, 2020
1 parent 8a623d7 commit 0528360
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 11 deletions.
24 changes: 24 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [Removed renderCurrentStory event](#removed-rendercurrentstory-event)
- [Removed hierarchy separators](#removed-hierarchy-separators)
- [Client API changes](#client-api-changes)
- [Removed support for duplicate kinds](#removed-support-for-duplicate-kinds)
- [Removed Legacy Story APIs](#removed-legacy-story-apis)
- [Can no longer add decorators/parameters after stories](#can-no-longer-add-decoratorsparameters-after-stories)
- [Changed Parameter Handling](#changed-parameter-handling)
Expand Down Expand Up @@ -414,6 +415,29 @@ addons.setConfig({

### Client API changes

#### Removed support for duplicate kinds

In 6.0 we removed the ability to split a kind's (component's) stories into multiple files because it was causing issues in hot module reloading (HMR).

If you had N stories that contained `export default { title: 'foo/bar' }` (or the MDX equivalent `<Meta title="foo/bar">`), Storybook will now throw the error `Duplicate title '${kindName}' used in multiple files`.

To split a component's stories into multiple files, e.g. for the `foo/bar` example above:

- Create a single file with the `export default { title: 'foo/bar' }` export, which is the primary file
- Comment out or delete the default export from the other files
- Re-export the stories from the other files in the primary file

So the primary example might look like:

```js
export default { title: 'foo/bar' };
export * from './Bar1.stories'
export * from './Bar2.stories'
export * from './Bar3.stories'

export const SomeStory = () => ...;
```

#### Removed Legacy Story APIs

In 6.0 we removed a set of APIs from the underlying `StoryStore` (which wasn't publicly accessible):
Expand Down
13 changes: 7 additions & 6 deletions addons/docs/docs/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ Perhaps you want to write your stories in CSF, but document them in MDX? Here's
import React from 'react';
import { Button } from './Button';

export default {
title: 'Demo/Button',
component: Button,
includeStories: [], // or don't load this file at all
};
// NOTE: no default export since `Button.stories.mdx` is the story file for `Button` now
//
// export default {
// title: 'Demo/Button',
// component: Button,
// };

export const basic = () => <Button>Basic</Button>;
basic.parameters = {
Expand All @@ -60,7 +61,7 @@ basic.parameters = {

```md
import { Meta, Story } from '@storybook/addon-docs/blocks';
import \* as stories from './Button.stories.js';
import * as stories from './Button.stories.js';
import { SomeComponent } from 'path/to/SomeComponent';

<Meta title="Demo/Button" component={Button} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import { Button } from '@storybook/react/demo';

export default {
title: 'Addons/Docs/csf-with-mdx-docs',
component: Button,
includeStories: [], // or don't load this file at all
};
// NOTE: commented out default since these stories are re-exported
// in the primary file './csf-docs-with-mdx-docs.stories.mdx'
//
// export default {
// title: 'Addons/Docs/csf-with-mdx-docs',
// component: Button,
// };

export const basic = () => <Button>Basic</Button>;
15 changes: 15 additions & 0 deletions lib/core/src/client/preview/loadCsf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ const loadStories = (
framework: string,
{ clientApi, storyStore }: { clientApi: ClientApi; storyStore: StoryStore }
) => () => {
// Make sure we don't try to define a kind more than once within the same load
const loadedKinds = new Set();

let reqs = null;
// todo discuss / improve type check
if (Array.isArray(loadable)) {
Expand Down Expand Up @@ -106,6 +109,18 @@ const loadStories = (
args: kindArgs,
argTypes: kindArgTypes,
} = meta;

if (loadedKinds.has(kindName)) {
throw new Error(
dedent`
Duplicate title '${kindName}' used in multiple files; use unique titles or a primary file for '${kindName}' with re-exported stories.
https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#removed-support-for-duplicate-kinds
`
);
}
loadedKinds.add(kindName);

// We pass true here to avoid the warning about HMR. It's cool clientApi, we got this
// todo discuss: TS now wants a NodeModule; should we fix this differently?
const kind = clientApi.storiesOf(kindName, true as any);
Expand Down

0 comments on commit 0528360

Please sign in to comment.