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

Core, Server, Addon-docs: Replace story indexers with new API #23660

Merged
merged 17 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 37 additions & 16 deletions code/addons/docs/src/preset.ts
Expand Up @@ -3,7 +3,7 @@ import remarkSlug from 'remark-slug';
import remarkExternalLinks from 'remark-external-links';
import { dedent } from 'ts-dedent';

import type { DocsOptions, Options, StorybookConfig, StoryIndexer } from '@storybook/types';
import type { DocsOptions, Indexer, Options, StorybookConfig } from '@storybook/types';
import type { CsfPluginOptions } from '@storybook/csf-plugin';
import type { JSXOptions, CompileOptions } from '@storybook/mdx2-csf';
import { global } from '@storybook/global';
Expand Down Expand Up @@ -129,23 +129,44 @@ async function webpack(
return result;
}

const storyIndexers: StorybookConfig['storyIndexers'] = (existingIndexers) => {
const mdxIndexer: StoryIndexer['indexer'] = async (fileName, opts) => {
export const createStoriesMdxIndexer = (legacyMdx1?: boolean): Indexer => ({
test: /(stories|story)\.mdx$/,
index: async (fileName, opts) => {
let code = (await fs.readFile(fileName, 'utf-8')).toString();
const { compile } = global.FEATURES?.legacyMdx1
const { compile } = legacyMdx1
? await import('@storybook/mdx1-csf')
: await import('@storybook/mdx2-csf');
code = await compile(code, {});
return loadCsf(code, { ...opts, fileName }).parse();
};
return [
{
test: /(stories|story)\.mdx$/,
indexer: mdxIndexer,
},
...(existingIndexers || []),
];
};
const csf = loadCsf(code, { ...opts, fileName }).parse();

// eslint-disable-next-line no-underscore-dangle
return Object.entries(csf._stories).map(([exportName, story]) => {
const docsOnly = story.parameters?.docsOnly;
const tags = (csf.meta.tags ?? []).concat(
story.tags ?? [],
docsOnly ? 'stories-mdx-docsOnly' : []
);

// the mdx-csf compiler automatically adds the 'stories-mdx' tag to meta, here' we're just making sure it is always there
if (!tags.includes('stories-mdx')) {
tags.push('stories-mdx');
}
return {
type: 'story',
importPath: fileName,
exportName,
name: story.name,
title: csf.meta.title,
metaId: csf.meta.id,
tags,
__id: story.id,
};
});
},
});

const indexers: StorybookConfig['indexers'] = (existingIndexers) =>
[createStoriesMdxIndexer(global.FEATURES?.legacyMdx1)].concat(existingIndexers || []);

const docs = (docsOptions: DocsOptions) => {
return {
Expand All @@ -164,9 +185,9 @@ export const addons: StorybookConfig['addons'] = [
* something down the dependency chain is using typescript namespaces, which are not supported by rollup-plugin-dts
*/
const webpackX = webpack as any;
const storyIndexersX = storyIndexers as any;
const indexersX = indexers as any;
const docsX = docs as any;

ensureReactPeerDeps();

export { webpackX as webpack, storyIndexersX as storyIndexers, docsX as docs };
export { webpackX as webpack, indexersX as indexers, docsX as docs };
2 changes: 1 addition & 1 deletion code/lib/cli/src/generators/SERVER/index.ts
Expand Up @@ -3,7 +3,7 @@ import type { Generator } from '../types';

const generator: Generator = async (packageManager, npmOptions, options) => {
await baseGenerator(packageManager, npmOptions, options, 'server', {
extensions: ['json'],
extensions: ['json', 'yaml', 'yml'],
});
};

Expand Down
1 change: 1 addition & 0 deletions code/lib/core-server/package.json
Expand Up @@ -98,6 +98,7 @@
"ws": "^8.2.3"
},
"devDependencies": {
"@storybook/addon-docs": "workspace:*",
"@types/compression": "^1.7.0",
"@types/ip": "^1.1.0",
"@types/node-fetch": "^2.5.7",
Expand Down
39 changes: 25 additions & 14 deletions code/lib/core-server/src/presets/common-preset.ts
Expand Up @@ -11,12 +11,12 @@ import {
import type {
CLIOptions,
CoreConfig,
Indexer,
Options,
PresetPropertyFn,
StorybookConfig,
StoryIndexer,
} from '@storybook/types';
import { loadCsf, printConfig, readConfig } from '@storybook/csf-tools';
import { printConfig, readConfig, readCsf } from '@storybook/csf-tools';
import { join } from 'path';
import { dedent } from 'ts-dedent';
import fetch from 'node-fetch';
Expand Down Expand Up @@ -194,20 +194,31 @@ export const features = async (
legacyDecoratorFileOrder: false,
});

export const storyIndexers: StorybookConfig['storyIndexers'] = async (existingIndexers) => {
const csfIndexer: StoryIndexer['indexer'] = async (fileName, opts) => {
const code = (await readFile(fileName, 'utf-8')).toString();
return loadCsf(code, { ...opts, fileName }).parse();
};
return [
{
test: /(stories|story)\.(m?js|ts)x?$/,
indexer: csfIndexer,
},
...(existingIndexers || []),
];
export const csfIndexer: Indexer = {
test: /\.stories\.(m?js|ts)x?$/,
index: async (fileName, options) => {
const csf = (await readCsf(fileName, options)).parse();

// eslint-disable-next-line no-underscore-dangle
return Object.entries(csf._stories).map(([exportName, story]) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this to a getter on CsfFile? The code seems to be duplicated all over the place and that would make this PR a lot more DRY.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CsfFile.indexEntries?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I've been thinking something similar, I'll experiment with a getter for indexInputs and stories with exportName so you don't need the funky use of _stories.

const tags = (csf.meta.tags ?? []).concat(story.tags ?? []);
return {
type: 'story',
importPath: fileName,
exportName,
name: story.name,
title: csf.meta.title,
metaId: csf.meta.id,
tags,
__id: story.id,
};
});
},
};

export const indexers: StorybookConfig['indexers'] = (existingIndexers) =>
[csfIndexer].concat(existingIndexers || []);

export const frameworkOptions = async (
_: never,
options: Options
Expand Down
Expand Up @@ -93,6 +93,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => {
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": Array [
"component-tag",
"story-tag",
"story",
],
Expand Down Expand Up @@ -163,6 +164,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => {
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": Array [
"component-tag",
"story-tag",
"story",
],
Expand Down Expand Up @@ -307,6 +309,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => {
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": Array [
"component-tag",
"story-tag",
"story",
],
Expand Down Expand Up @@ -666,6 +669,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => {
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": Array [
"component-tag",
"story-tag",
"story",
],
Expand Down Expand Up @@ -792,6 +796,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => {
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": Array [
"component-tag",
"story-tag",
"story",
],
Expand Down Expand Up @@ -914,6 +919,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => {
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": Array [
"component-tag",
"story-tag",
"story",
],
Expand Down Expand Up @@ -980,6 +986,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => {
"importPath": "./src/A.stories.js",
"name": "Story One",
"tags": Array [
"component-tag",
"story-tag",
"story",
],
Expand Down