Skip to content
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

Release: Prerelease 8.2.0-beta.1 #28463

Merged
merged 49 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
24019b5
Blocks: Prebundle tocbot
shilman Jun 23, 2024
86ac7f0
Merge branch 'next' into shilman/28307-prebundle-tocbot
shilman Jul 3, 2024
e09a283
Fix markdown link
ROCKTAKEY Jul 4, 2024
c59e9bb
Merge pull request #28458 from ROCKTAKEY/fix-contributing-link
jonniebigodes Jul 4, 2024
68c5eac
Index: Fix MDX to override project-level autodocs
shilman Jul 5, 2024
14ef5cc
Fix test
shilman Jul 5, 2024
d956ca6
Merge pull request #28461 from storybookjs/shilman/fix-mdx-autodocs-c…
shilman Jul 5, 2024
71989a3
Proposal
kasperpeulen Jul 5, 2024
e6a2947
Merge pull request #28318 from storybookjs/shilman/28307-prebundle-to…
shilman Jul 5, 2024
0bd760a
migrate all errors to the new format
yannbf Jul 5, 2024
d65b117
rename template to message
yannbf Jul 5, 2024
ea9dd8c
update error docs
yannbf Jul 5, 2024
4e4e6c0
fix eslint issues and migrate detection to the new error format
yannbf Jul 5, 2024
f54e780
update NoStoryMountedError error
yannbf Jul 5, 2024
b19260a
Improve MountMustBeDestructuredError error message
kasperpeulen Jul 5, 2024
37169b7
Make sure that stories files get not transpiled by babel further than…
kasperpeulen Jul 5, 2024
6402da4
Fix ready check for compile after CPC
kasperpeulen Jul 5, 2024
9d1b00c
Merge branch 'next' into kasper/error-handling
kasperpeulen Jul 5, 2024
e636fa0
Merge branch 'refs/heads/kasper/error-handling' into kasper/improve-e…
kasperpeulen Jul 5, 2024
8888f64
Fix wrong refactor
kasperpeulen Jul 5, 2024
246dd98
Improve indentation
kasperpeulen Jul 5, 2024
5dc7c1d
Fix wrong refactor
kasperpeulen Jul 5, 2024
43315c2
Merge branch 'refs/heads/kasper/error-handling' into kasper/improve-e…
kasperpeulen Jul 5, 2024
8d1bca5
Merge branch 'refs/heads/kasper/improve-error-message' into kasper/ba…
kasperpeulen Jul 5, 2024
65d45ab
Seems like a wrong refactor
kasperpeulen Jul 5, 2024
26e0c9b
Merge branch 'kasper/error-handling' into kasper/improve-error-message
kasperpeulen Jul 5, 2024
4cfc77e
Merge branch 'kasper/improve-error-message' into kasper/babel-fixes
kasperpeulen Jul 5, 2024
a0f8189
Seems like a wrong refactor
kasperpeulen Jul 5, 2024
13caa9a
Merge branch 'kasper/error-handling' into kasper/improve-error-message
kasperpeulen Jul 5, 2024
f61df60
Merge branch 'kasper/improve-error-message' into kasper/babel-fixes
kasperpeulen Jul 5, 2024
93002de
Revert dedent import
kasperpeulen Jul 5, 2024
57a656b
Merge branch 'kasper/error-handling' into kasper/improve-error-message
kasperpeulen Jul 5, 2024
c237511
Merge branch 'kasper/improve-error-message' into kasper/babel-fixes
kasperpeulen Jul 5, 2024
19fbf2f
Fix indent
kasperpeulen Jul 5, 2024
b0a9b90
Merge branch 'kasper/error-handling' into kasper/improve-error-message
kasperpeulen Jul 5, 2024
109b3b7
Merge branch 'kasper/improve-error-message' into kasper/babel-fixes
kasperpeulen Jul 5, 2024
504e7c7
Update code/core/src/preview-errors.ts
kasperpeulen Jul 6, 2024
d81bba3
Align templates and address feedback
kasperpeulen Jul 6, 2024
93cd45f
Improve babel override
kasperpeulen Jul 6, 2024
13338a2
Adress feedback and fix unit test
kasperpeulen Jul 7, 2024
5c19998
Merge branch 'refs/heads/kasper/error-handling' into kasper/improve-e…
kasperpeulen Jul 7, 2024
567aa02
Merge pull request #28470 from storybookjs/kasper/ready-check
kasperpeulen Jul 7, 2024
7ed7ea4
Merge branch 'kasper/improve-error-message' into kasper/babel-fixes
kasperpeulen Jul 7, 2024
3a88baa
Merge pull request #28464 from storybookjs/kasper/error-handling
kasperpeulen Jul 7, 2024
3861885
Merge pull request #28468 from storybookjs/kasper/improve-error-message
kasperpeulen Jul 7, 2024
286d84c
Fix
kasperpeulen Jul 7, 2024
5b884b6
Update code/frameworks/nextjs/src/preset.ts
kasperpeulen Jul 8, 2024
dd1f7f0
Merge pull request #28469 from storybookjs/kasper/babel-fixes
valentinpalkovic Jul 8, 2024
afb0dd1
Write changelog for 8.2.0-beta.1 [skip ci]
storybook-bot Jul 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.prerelease.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 8.2.0-beta.1

- Babel: Ensure story files not transpiled earlier than ES2017 - [#28469](https://github.com/storybookjs/storybook/pull/28469), thanks @kasperpeulen!
- Blocks: Prebundle `tocbot` - [#28318](https://github.com/storybookjs/storybook/pull/28318), thanks @shilman!
- Core: Make sure StorybookError message shows up in browser console and interactions panel - [#28464](https://github.com/storybookjs/storybook/pull/28464), thanks @kasperpeulen!
- Index: Fix MDX to override project-level autodocs - [#28461](https://github.com/storybookjs/storybook/pull/28461), thanks @shilman!
- Test: Improve MountMustBeDestructuredError error message - [#28468](https://github.com/storybookjs/storybook/pull/28468), thanks @kasperpeulen!

## 8.2.0-beta.0

- Addon Interactions: Use unique keys when rendering array nodes in panel - [#28423](https://github.com/storybookjs/storybook/pull/28423), thanks @yannbf!
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ You will need to have the following installed:
- git
- node
- yarn
- (bun)[https://bun.sh/]
- [bun](https://bun.sh/)

## Using fnm as a Node version manager

Expand Down
2 changes: 1 addition & 1 deletion code/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ module.exports = {
},
},
{
files: ['**/core-events/src/**/*'],
files: ['./core/src/preview-errors.ts'],
excludedFiles: ['**/*.test.*'],
rules: {
'local-rules/no-duplicated-error-codes': 'error',
Expand Down
44 changes: 23 additions & 21 deletions code/core/src/ERRORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ Second use the `StorybookError` class to define custom errors with specific code
```typescript
import { StorybookError } from './storybook-error';
export class YourCustomError extends StorybookError {
readonly category: Category; // The category to which the error belongs. Check the source in client-errors.ts or server-errors.ts for reference.
readonly code: number; // The numeric code for the error.

template(): string {
// A function that returns the error message.
constructor() {
super({
// The category to which the error belongs. Check the source in client-errors.ts or server-errors.ts for reference.
category: Category,
// The numeric code for the error.
code: number,
// The error message.
message: string,
});
}
}
```
Expand All @@ -42,7 +46,7 @@ export class YourCustomError extends StorybookError {
| ------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| category | `Category` | The category to which the error belongs. |
| code | `number` | The numeric code for the error. |
| template | `() => string` | Function that returns a properly written error message. |
| message | `string` | The error message. |
| data | `Object` | Optional. Data associated with the error. Used to provide additional information in the error message or to be passed to telemetry. |
| documentation | `boolean` or `string` | Optional. Should be set to `true` **if the error is documented on the Storybook website**. If defined as string, it should be a custom documentation link. |

Expand All @@ -51,28 +55,26 @@ export class YourCustomError extends StorybookError {
```typescript
// Define a custom error with a numeric code and a static error message template.
export class StorybookIndexGenerationError extends StorybookError {
category = Category.Generic;
code = 1;

template(): string {
return `Storybook failed when generating an index for your stories. Check the stories field in your main.js`;
constructor() {
super({
category: Category.Generic,
code: 1,
message: `Storybook failed when generating an index for your stories. Check the stories field in your main.js`,
});
}
}

// Define a custom error with a numeric code and a dynamic error message template based on properties from the constructor.
// Define a custom error with a numeric code and a dynamic error message based on properties from the constructor.
export class InvalidFileExtensionError extends StorybookError {
category = Category.Validation;
code = 2;
documentation = 'https://some-custom-documentation.com/validation-errors';

// extra properties are defined in the constructor via a data property, which is available in any class method
// always use this data Object notation!
constructor(public data: { extension: string }) {
super();
}

template(): string {
return `Invalid file extension found: ${this.data.extension}.`;
super({
category: Category.Validation,
code: 2,
documentation: 'https://some-custom-documentation.com/validation-errors',
message: `Invalid file extension found: ${data.extension}.`,
});
}
}

Expand Down
1 change: 0 additions & 1 deletion code/core/src/__tests/preview-errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ describe('UnknownFlowArgTypesError', () => {
const typeError = new UnknownArgTypesError({ type, language: 'Typescript' });
expect(typeError.message).toMatchInlineSnapshot(`
"There was a failure when generating detailed ArgTypes in Typescript for:

{
"name": "signature",
"raw": "SomeType['someProperty']"
Expand Down
24 changes: 11 additions & 13 deletions code/core/src/__tests/storybook-error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { StorybookError } from '../storybook-error';

describe('StorybookError', () => {
class TestError extends StorybookError {
category = 'TEST_CATEGORY';

code = 123;

template() {
return 'This is a test error.';
constructor(documentation?: StorybookError['documentation']) {
super({
category: 'TEST_CATEGORY',
code: 123,
message: 'This is a test error.',
documentation,
});
}
}

Expand All @@ -24,16 +25,14 @@ describe('StorybookError', () => {
});

it('should generate the correct message with internal documentation link', () => {
const error = new TestError();
error.documentation = true;
const error = new TestError(true);
const expectedMessage =
'This is a test error.\n\nMore info: https://storybook.js.org/error/SB_TEST_CATEGORY_0123\n';
expect(error.message).toBe(expectedMessage);
});

it('should generate the correct message with external documentation link', () => {
const error = new TestError();
error.documentation = 'https://example.com/docs/test-error';
const error = new TestError('https://example.com/docs/test-error');
expect(error.message).toMatchInlineSnapshot(`
"This is a test error.

Expand All @@ -43,11 +42,10 @@ describe('StorybookError', () => {
});

it('should generate the correct message with multiple external documentation links', () => {
const error = new TestError();
error.documentation = [
const error = new TestError([
'https://example.com/docs/first-error',
'https://example.com/docs/second-error',
];
]);
expect(error.message).toMatchInlineSnapshot(`
"This is a test error.

Expand Down
32 changes: 30 additions & 2 deletions code/core/src/core-server/presets/common-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,36 @@ export const favicon = async (

export const babel = async (_: unknown, options: Options) => {
const { presets } = options;

return presets.apply('babelDefault', {}, options);
const babelDefault = ((await presets.apply('babelDefault', {}, options)) ?? {}) as Record<
string,
any
>;
return {
...babelDefault,
// This override makes sure that we will never transpile babel further down then the browsers that storybook supports.
// This is needed to support the mount property of the context described here:
// https://storybook.js.org/docs/writing-tests/interaction-testing#run-code-before-each-test
overrides: [
...(babelDefault?.overrides ?? []),
{
include: /\.(story|stories)\.[cm]?[jt]sx?$/,
presets: [
[
'@babel/preset-env',
{
bugfixes: true,
targets: {
// This is the same browser supports that we use to bundle our manager and preview code.
chrome: 100,
safari: 15,
firefox: 91,
},
},
],
],
},
],
};
};

export const title = (previous: string, options: Options) =>
Expand Down
115 changes: 112 additions & 3 deletions code/core/src/core-server/utils/StoryIndexGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,43 @@ describe('StoryIndexGenerator', () => {
`);
});

it('adds the autodocs tag to the autogenerated docs entries', async () => {
it('generates an entry for every CSF file when projectTags contains autodocs', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

const generator = new StoryIndexGenerator([specifier], autodocsOptions);
generator.getProjectTags = () => ['dev', 'test', 'autodocs'];
await generator.initialize();

expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(`
[
"a--docs",
"a--story-one",
"b--docs",
"b--story-one",
"d--docs",
"d--story-one",
"h--docs",
"h--story-one",
"componentpath-extension--docs",
"componentpath-extension--story-one",
"componentpath-noextension--docs",
"componentpath-noextension--story-one",
"componentpath-package--docs",
"componentpath-package--story-one",
"first-nested-deeply-f--docs",
"first-nested-deeply-f--story-one",
"nested-button--docs",
"nested-button--story-one",
"second-nested-g--docs",
"second-nested-g--story-one",
]
`);
});

it('adds the autodocs tag to the autogenerated docs entries when docsOptions.autodocs = true', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
Expand All @@ -626,6 +662,22 @@ describe('StoryIndexGenerator', () => {
);
});

it('adds the autodocs tag to the autogenerated docs entries when projectTags contains autodocs', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

const generator = new StoryIndexGenerator([specifier], autodocsOptions);
generator.getProjectTags = () => ['dev', 'test', 'autodocs'];
await generator.initialize();

const index = await generator.getIndex();
expect(index.entries['first-nested-deeply-f--docs'].tags).toEqual(
expect.arrayContaining(['autodocs'])
);
});

it('throws an error if you attach a named MetaOf entry which clashes with a tagged autodocs entry', async () => {
const csfSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/B.stories.ts',
Expand Down Expand Up @@ -793,7 +845,7 @@ describe('StoryIndexGenerator', () => {
`);
});

it('allows you to override autodocs with MetaOf if it is automatic', async () => {
it('allows you to override autodocs with MetaOf when docsOptions.autodocs = true', async () => {
const csfSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.js',
options
Expand Down Expand Up @@ -852,6 +904,63 @@ describe('StoryIndexGenerator', () => {
`);
});

it('allows you to override autodocs with MetaOf when projectTags contains autodocs', async () => {
const csfSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.js',
options
);

const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./errors/A.mdx',
options
);

const generator = new StoryIndexGenerator([csfSpecifier, docsSpecifier], autodocsOptions);
generator.getProjectTags = () => ['dev', 'test', 'autodocs'];
await generator.initialize();

expect(await generator.getIndex()).toMatchInlineSnapshot(`
{
"entries": {
"a--docs": {
"id": "a--docs",
"importPath": "./errors/A.mdx",
"name": "docs",
"storiesImports": [
"./src/A.stories.js",
],
"tags": [
"dev",
"test",
"autodocs",
"component-tag",
"story-tag",
"attached-mdx",
],
"title": "A",
"type": "docs",
},
"a--story-one": {
"componentPath": undefined,
"id": "a--story-one",
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": [
"dev",
"test",
"autodocs",
"component-tag",
"story-tag",
],
"title": "A",
"type": "story",
},
},
"v": 5,
}
`);
});

it('generates a combined entry if there are two stories files for the same title', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./duplicate/*.stories.(ts|js|mjs|jsx)',
Expand Down Expand Up @@ -1418,7 +1527,7 @@ describe('StoryIndexGenerator', () => {
type: 'story',
};
expect(() => {
generator.chooseDuplicate(mockEntry, { ...mockEntry, importPath: 'DifferentPath' });
generator.chooseDuplicate(mockEntry, { ...mockEntry, importPath: 'DifferentPath' }, []);
}).toThrowErrorMatchingInlineSnapshot(`[Error: Duplicate stories with id: StoryId]`);
});

Expand Down
13 changes: 8 additions & 5 deletions code/core/src/core-server/utils/StoryIndexGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ export class StoryIndexGenerator {
}
}

chooseDuplicate(firstEntry: IndexEntry, secondEntry: IndexEntry): IndexEntry {
chooseDuplicate(firstEntry: IndexEntry, secondEntry: IndexEntry, projectTags: Tag[]): IndexEntry {
// NOTE: it is possible for the same entry to show up twice (if it matches >1 glob). That's OK.
if (firstEntry.importPath === secondEntry.importPath) {
return firstEntry;
Expand Down Expand Up @@ -555,13 +555,16 @@ export class StoryIndexGenerator {
}

// If you link a file to a tagged CSF file, you have probably made a mistake
if (worseEntry.tags?.includes(AUTODOCS_TAG) && this.options.docs.autodocs !== true)
if (
worseEntry.tags?.includes(AUTODOCS_TAG) &&
!(this.options.docs.autodocs === true || projectTags?.includes(AUTODOCS_TAG))
)
throw new IndexingError(
`You created a component docs page for '${worseEntry.title}', but also tagged the CSF file with '${AUTODOCS_TAG}'. This is probably a mistake.`,
[betterEntry.importPath, worseEntry.importPath]
);

// Otherwise the existing entry is created by `autodocs=true` which allowed to be overridden.
// Otherwise the existing entry is created by project-level autodocs which is allowed to be overridden.
} else {
// If both entries are templates (e.g. you have two CSF files with the same title), then
// we need to merge the entries. We'll use the first one's name and importPath,
Expand Down Expand Up @@ -617,7 +620,7 @@ export class StoryIndexGenerator {
try {
const existing = indexEntries[entry.id];
if (existing) {
indexEntries[entry.id] = this.chooseDuplicate(existing, entry);
indexEntries[entry.id] = this.chooseDuplicate(existing, entry, projectTags);
} else {
indexEntries[entry.id] = entry;
}
Expand Down Expand Up @@ -709,7 +712,7 @@ export class StoryIndexGenerator {
}

getProjectTags(previewCode?: string) {
let projectTags = [];
let projectTags = [] as Tag[];
const defaultTags = ['dev', 'test'];
const extraTags = this.options.docs.autodocs === true ? [AUTODOCS_TAG] : [];
if (previewCode) {
Expand Down
Loading