Skip to content

Commit

Permalink
detect empty stories field and throw an error
Browse files Browse the repository at this point in the history
  • Loading branch information
yannbf committed Aug 24, 2023
1 parent 0d1960e commit 3ef5375
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
35 changes: 29 additions & 6 deletions code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
/// <reference path="../../test-typings.d.ts" />

import { dedent } from 'ts-dedent';
import { sep } from 'path';

import { normalizeStoriesEntry } from '../normalize-stories';
import { InvalidStoriesEntryError } from '@storybook/core-events/server-errors';
import {
getDirectoryFromWorkingDir,
normalizeStories,
normalizeStoriesEntry,
} from '../normalize-stories';

expect.addSnapshotSerializer({
print: (val: any) => JSON.stringify(val, null, 2),
Expand Down Expand Up @@ -47,12 +53,12 @@ jest.mock('fs', () => {
};
});

describe('normalizeStoriesEntry', () => {
const options = {
configDir: '/path/to/project/.storybook',
workingDir: '/path/to/project',
};
const options = {
configDir: '/path/to/project/.storybook',
workingDir: '/path/to/project',
};

describe('normalizeStoriesEntry', () => {
it('direct file path', () => {
const specifier = normalizeStoriesEntry('../path/to/file.stories.mdx', options);
expect(specifier).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -310,3 +316,20 @@ describe('normalizeStoriesEntry', () => {
]);
});
});

describe('getDirectoryFromWorkingDir', () => {
it('should return normalized story path', () => {
const normalizedPath = getDirectoryFromWorkingDir({
configDir: '/path/to/project/.storybook',
workingDir: '/path/to/project',
directory: '/path/to/project/src',
});
expect(normalizedPath).toBe(`.${sep}src`);
});
});

describe('normalizeStories', () => {
it('should throw InvalidStoriesEntryError for empty entries', () => {
expect(() => normalizeStories([], options)).toThrow(InvalidStoriesEntryError);
});
});
10 changes: 8 additions & 2 deletions code/lib/core-common/src/utils/normalize-stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as pico from 'picomatch';
import slash from 'slash';

import type { StoriesEntry, NormalizedStoriesSpecifier } from '@storybook/types';
import { InvalidStoriesEntryError } from '@storybook/core-events/server-errors';
import { normalizeStoryPath } from './paths';
import { globToRegexp } from './glob-to-regexp';

Expand Down Expand Up @@ -100,5 +101,10 @@ interface NormalizeOptions {
workingDir: string;
}

export const normalizeStories = (entries: StoriesEntry[], options: NormalizeOptions) =>
entries.map((entry) => normalizeStoriesEntry(entry, options));
export const normalizeStories = (entries: StoriesEntry[], options: NormalizeOptions) => {
if (!entries || (Array.isArray(entries) && entries.length === 0)) {
throw new InvalidStoriesEntryError();
}

return entries.map((entry) => normalizeStoriesEntry(entry, options));
};
18 changes: 18 additions & 0 deletions code/lib/core-events/src/errors/server-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,21 @@ export class ConflictingStaticDirConfigError extends StorybookError {
`;
}
}

export class InvalidStoriesEntryError extends StorybookError {
readonly category = Category.CORE_COMMON;

readonly code = 4;

public readonly documentation =
'https://storybook.js.org/docs/react/faq#can-i-have-a-storybook-with-no-local-stories';

template() {
return dedent`
Storybook could not index your stories.
Your main configuration somehow does not contain a 'stories' field, or it resolved to an empty array.
Please check your main configuration file and make sure it exports a 'stories' field that is not an empty array.
`;
}
}
31 changes: 31 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Here are some answers to frequently asked questions. If you have a question, you
- [Why is there no addons channel?](#why-is-there-no-addons-channel)
- [Why aren't Controls visible in the Canvas panel but visible in Docs?](#why-arent-controls-visible-in-the-canvas-panel-but-visible-in-docs)
- [Why aren't the addons working in a composed Storybook?](#why-arent-the-addons-working-in-a-composed-storybook)
- [Can I have a Storybook with no local stories?](#can-i-have-a-storybook-with-no-local-stories)
- [Which community addons are compatible with the latest version of Storybook?](#which-community-addons-are-compatible-with-the-latest-version-of-storybook)
- [Is it possible to browse the documentation for past versions of Storybook?](#is-it-possible-to-browse-the-documentation-for-past-versions-of-storybook)
- [What icons are available for my toolbar or my addon?](#what-icons-are-available-for-my-toolbar-or-my-addon)
Expand Down Expand Up @@ -218,6 +219,36 @@ For now, the addons you're using in a composed Storybook will not work.

We're working on overcoming this limitation, and soon you'll be able to use them as if you are working with a non-composed Storybook.

## Can I have a Storybook with no local stories?

Storybook does not work unless you define at least one local story.

If you're in a Storybook composition scenario, where you have multiple Storybooks, and want to have an extra Storybook with no stories of its own, that serves as a "glue" for all the other Storybooks in a project for demo/documentation purposes, you can do the following steps:

Introduce a single `.mdx` story (addon-essentials or addon-docs required), that serves as an Introduction page, like so:

```mdx
// Introduction.mdx
# Welcome

Some description here
```

And then refer to it in your main.js file:

```ts
// .storybook/main.js
const config = {
stories: ['../Introduction.mdx'],
refs: {
firstProject: { title: 'First', url: 'some-url' },
secondProject: { title: 'Second', url: 'other-url' },
}
// ...
}
export default config;
```

## Which community addons are compatible with the latest version of Storybook?

Starting with Storybook version 6.0, we've introduced some great features aimed at streamlining your development workflow.
Expand Down

0 comments on commit 3ef5375

Please sign in to comment.