Skip to content

Commit

Permalink
Merge pull request #23125 from idesigncode/my-first-storybook-contrib…
Browse files Browse the repository at this point in the history
…ution

Core: Allow `.mjs` extension for CSF stories
  • Loading branch information
ndelangen authored Jun 21, 2023
2 parents 7cd93d3 + a0fe377 commit 4311d33
Show file tree
Hide file tree
Showing 143 changed files with 281 additions and 174 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ describe('bare-mdx fix', () => {
};
const main = {
stories: [
'../src/**/*.stories.@(js|jsx|ts|tsx)',
{ directory: '../**', files: '*.stories.@(js|jsx|ts|tsx)' },
'../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
{ directory: '../**', files: '*.stories.@(js|jsx|mjs|ts|tsx)' },
{ directory: '../**' },
],
};
Expand Down
6 changes: 3 additions & 3 deletions code/lib/cli/src/generators/configure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('configureMain', () => {
expect(mainConfigContent).toMatchInlineSnapshot(`
"/** @type { import('@storybook/react-vite').StorybookConfig } */
const config = {
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [],
framework: {
name: '@storybook/react-vite',
Expand Down Expand Up @@ -55,7 +55,7 @@ describe('configureMain', () => {
expect(mainConfigContent).toMatchInlineSnapshot(`
"import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [],
framework: {
name: '@storybook/react-vite',
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('configureMain', () => {
/** @type { import('@storybook/react-webpack5').StorybookConfig } */
const config = {
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
path.dirname(require.resolve(path.join('@storybook/addon-links', 'package.json'))),
path.dirname(require.resolve(path.join('@storybook/addon-essentials', 'package.json'))),
Expand Down
2 changes: 1 addition & 1 deletion code/lib/cli/src/generators/configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const sanitizeFramework = (framework: string) => {

export async function configureMain({
addons,
extensions = ['js', 'jsx', 'ts', 'tsx'],
extensions = ['js', 'jsx', 'mjs', 'ts', 'tsx'],
storybookConfigFolder,
language,
...custom
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ describe('normalizeStoriesEntry', () => {
{
"titlePrefix": "",
"directory": ".",
"files": "**/*.@(mdx|stories.@(tsx|ts|jsx|js))",
"files": "**/*.@(mdx|stories.@(js|jsx|mjs|ts|tsx))",
"importPathMatcher": {}
}
`);
Expand All @@ -241,7 +241,7 @@ describe('normalizeStoriesEntry', () => {
expect(specifier).toMatchInlineSnapshot(`
{
"titlePrefix": "",
"files": "**/*.@(mdx|stories.@(tsx|ts|jsx|js))",
"files": "**/*.@(mdx|stories.@(js|jsx|mjs|ts|tsx))",
"directory": ".",
"importPathMatcher": {}
}
Expand All @@ -265,7 +265,7 @@ describe('normalizeStoriesEntry', () => {
expect(specifier).toMatchInlineSnapshot(`
{
"titlePrefix": "atoms",
"files": "**/*.@(mdx|stories.@(tsx|ts|jsx|js))",
"files": "**/*.@(mdx|stories.@(js|jsx|mjs|ts|tsx))",
"directory": ".",
"importPathMatcher": {}
}
Expand Down
2 changes: 1 addition & 1 deletion code/lib/core-common/src/utils/normalize-stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { normalizeStoryPath } from './paths';
import { globToRegexp } from './glob-to-regexp';

const DEFAULT_TITLE_PREFIX = '';
const DEFAULT_FILES = '**/*.@(mdx|stories.@(tsx|ts|jsx|js))';
const DEFAULT_FILES = '**/*.@(mdx|stories.@(js|jsx|mjs|ts|tsx))';

const isDirectory = (configDir: string, entry: string) => {
try {
Expand Down
2 changes: 1 addition & 1 deletion code/lib/core-server/src/presets/common-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export const storyIndexers = async (indexers?: StoryIndexer[]) => {
};
return [
{
test: /(stories|story)\.[tj]sx?$/,
test: /(stories|story)\.(m?js|ts)x?$/,
indexer: csfIndexer,
},
...(indexers || []),
Expand Down
87 changes: 62 additions & 25 deletions code/lib/core-server/src/utils/StoryIndexGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const options = {
workingDir: path.join(__dirname, '__mockdata__'),
storyIndexers: [
{ test: /\.stories\.mdx$/, indexer: storiesMdxIndexer },
{ test: /\.stories\.(js|ts)x?$/, indexer: csfIndexer },
{ test: /\.stories\.(m?js|ts)x?$/, indexer: csfIndexer },
] as StoryIndexer[],
storiesV2Compatibility: false,
storyStoreV7: true,
Expand All @@ -65,7 +65,7 @@ describe('StoryIndexGenerator', () => {
});
describe('extraction', () => {
const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.(ts|js|jsx)',
'./src/A.stories.(ts|js|mjs|jsx)',
options
);
const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
Expand Down Expand Up @@ -106,7 +106,7 @@ describe('StoryIndexGenerator', () => {
describe('non-recursive specifier', () => {
it('extracts stories from the right files', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/*/*.stories.(ts|js|jsx)',
'./src/*/*.stories.(ts|js|mjs|jsx)',
options
);

Expand Down Expand Up @@ -147,7 +147,7 @@ describe('StoryIndexGenerator', () => {
describe('recursive specifier', () => {
it('extracts stories from the right files', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

Expand Down Expand Up @@ -200,6 +200,17 @@ describe('StoryIndexGenerator', () => {
"title": "first-nested/deeply/F",
"type": "story",
},
"h--story-one": Object {
"id": "h--story-one",
"importPath": "./src/H.stories.mjs",
"name": "Story One",
"tags": Array [
"autodocs",
"story",
],
"title": "H",
"type": "story",
},
"nested-button--story-one": Object {
"id": "nested-button--story-one",
"importPath": "./src/nested/Button.stories.ts",
Expand Down Expand Up @@ -280,7 +291,7 @@ describe('StoryIndexGenerator', () => {
};
it('generates an entry per CSF file with the autodocs tag', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

Expand Down Expand Up @@ -357,6 +368,29 @@ describe('StoryIndexGenerator', () => {
"title": "first-nested/deeply/F",
"type": "story",
},
"h--docs": Object {
"id": "h--docs",
"importPath": "./src/H.stories.mjs",
"name": "docs",
"storiesImports": Array [],
"tags": Array [
"autodocs",
"docs",
],
"title": "H",
"type": "docs",
},
"h--story-one": Object {
"id": "h--story-one",
"importPath": "./src/H.stories.mjs",
"name": "Story One",
"tags": Array [
"autodocs",
"story",
],
"title": "H",
"type": "story",
},
"nested-button--story-one": Object {
"id": "nested-button--story-one",
"importPath": "./src/nested/Button.stories.ts",
Expand Down Expand Up @@ -393,7 +427,7 @@ describe('StoryIndexGenerator', () => {
};
it('generates an entry for every CSF file when docsOptions.autodocs = true', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

Expand All @@ -408,6 +442,8 @@ describe('StoryIndexGenerator', () => {
"b--story-one",
"d--docs",
"d--story-one",
"h--docs",
"h--story-one",
"first-nested-deeply-f--docs",
"first-nested-deeply-f--story-one",
"nested-button--docs",
Expand All @@ -420,7 +456,7 @@ describe('StoryIndexGenerator', () => {

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

Expand Down Expand Up @@ -643,7 +679,7 @@ describe('StoryIndexGenerator', () => {

it('generates a combined entry if there are two stories files for the same title', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./duplicate/*.stories.(ts|js|jsx)',
'./duplicate/*.stories.(ts|js|mjs|jsx)',
options
);

Expand Down Expand Up @@ -1121,7 +1157,7 @@ describe('StoryIndexGenerator', () => {
describe('sorting', () => {
it('runs a user-defined sort function', async () => {
const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);
const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
Expand All @@ -1148,6 +1184,7 @@ describe('StoryIndexGenerator', () => {
"second-nested-g--story-one",
"componentreference--docs",
"notitle--docs",
"h--story-one",
"first-nested-deeply-f--story-one",
]
`);
Expand All @@ -1158,15 +1195,15 @@ describe('StoryIndexGenerator', () => {
describe('no invalidation', () => {
it('does not extract csf files a second time', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

loadCsfMock.mockClear();
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(loadCsfMock).toHaveBeenCalledTimes(6);
expect(loadCsfMock).toHaveBeenCalledTimes(7);

loadCsfMock.mockClear();
await generator.getIndex();
Expand All @@ -1175,7 +1212,7 @@ describe('StoryIndexGenerator', () => {

it('does not extract docs files a second time', async () => {
const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.(ts|js|jsx)',
'./src/A.stories.(ts|js|mjs|jsx)',
options
);
const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
Expand All @@ -1195,7 +1232,7 @@ describe('StoryIndexGenerator', () => {

it('does not call the sort function a second time', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

Expand All @@ -1215,15 +1252,15 @@ describe('StoryIndexGenerator', () => {
describe('file changed', () => {
it('calls extract csf file for just the one file', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

loadCsfMock.mockClear();
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(loadCsfMock).toHaveBeenCalledTimes(6);
expect(loadCsfMock).toHaveBeenCalledTimes(7);

generator.invalidate(specifier, './src/B.stories.ts', false);

Expand All @@ -1234,7 +1271,7 @@ describe('StoryIndexGenerator', () => {

it('calls extract docs file for just the one file', async () => {
const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.(ts|js|jsx)',
'./src/A.stories.(ts|js|mjs|jsx)',
options
);
const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
Expand All @@ -1256,7 +1293,7 @@ describe('StoryIndexGenerator', () => {

it('calls extract for a csf file and any of its docs dependents', async () => {
const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.(ts|js|jsx)',
'./src/A.stories.(ts|js|mjs|jsx)',
options
);
const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
Expand All @@ -1278,7 +1315,7 @@ describe('StoryIndexGenerator', () => {

it('does call the sort function a second time', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

Expand All @@ -1300,15 +1337,15 @@ describe('StoryIndexGenerator', () => {
describe('file removed', () => {
it('does not extract csf files a second time', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

loadCsfMock.mockClear();
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(loadCsfMock).toHaveBeenCalledTimes(6);
expect(loadCsfMock).toHaveBeenCalledTimes(7);

generator.invalidate(specifier, './src/B.stories.ts', true);

Expand All @@ -1319,7 +1356,7 @@ describe('StoryIndexGenerator', () => {

it('does call the sort function a second time', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

Expand All @@ -1339,15 +1376,15 @@ describe('StoryIndexGenerator', () => {

it('does not include the deleted stories in results', async () => {
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/**/*.stories.(ts|js|jsx)',
'./src/**/*.stories.(ts|js|mjs|jsx)',
options
);

loadCsfMock.mockClear();
const generator = new StoryIndexGenerator([specifier], options);
await generator.initialize();
await generator.getIndex();
expect(loadCsfMock).toHaveBeenCalledTimes(6);
expect(loadCsfMock).toHaveBeenCalledTimes(7);

generator.invalidate(specifier, './src/B.stories.ts', true);

Expand All @@ -1356,7 +1393,7 @@ describe('StoryIndexGenerator', () => {

it('does not include the deleted docs in results', async () => {
const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.(ts|js|jsx)',
'./src/A.stories.(ts|js|mjs|jsx)',
options
);
const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
Expand All @@ -1378,7 +1415,7 @@ describe('StoryIndexGenerator', () => {

it('cleans up properly on dependent docs deletion', async () => {
const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
'./src/A.stories.(ts|js|jsx)',
'./src/A.stories.(ts|js|mjs|jsx)',
options
);
const docsSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(
Expand Down
8 changes: 8 additions & 0 deletions code/lib/core-server/src/utils/__mockdata__/src/H.stories.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const component = {};

export default {
component,
tags: ['autodocs'],
};

export const StoryOne = {};
Loading

0 comments on commit 4311d33

Please sign in to comment.