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

Indexing: Introduce new experimental indexer API - NESTED PR! #23691

Merged
merged 66 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
380ee68
add indexers config, deprecate storyIndexers
JReinhold Jul 24, 2023
e1d732f
Add Indexer type
JReinhold Jul 24, 2023
239d89d
add types for new indexer
JReinhold Jul 24, 2023
7051481
add test for deprecated API
JReinhold Jul 24, 2023
3fcb9df
add new index type, move StoryIndexGenerator tests
JReinhold Jul 24, 2023
ba63c5f
revert back to storyIndexers
JReinhold Jul 24, 2023
9061c6e
add support for storyIndexers and indexers in StoryIndexGenerator
JReinhold Jul 24, 2023
73a32be
improve type docs
JReinhold Jul 24, 2023
fd9a895
fix unit tests
JReinhold Jul 24, 2023
41d8e12
separate IndexEntry from new IndexInput - improve CsfFile.parse type
JReinhold Jul 25, 2023
9bd0404
start on tests
JReinhold Jul 26, 2023
898f019
Merge pull request #23582 from storybookjs/new-indexer-api
JReinhold Jul 26, 2023
213bb01
refactor extractStories to deprecated function
JReinhold Jul 26, 2023
1031683
support minimal and full indexer inputs
JReinhold Jul 26, 2023
fd54fa2
add basic csf indexer to tests
JReinhold Jul 26, 2023
d01d9a6
add docs entries based on tags
JReinhold Jul 26, 2023
992efe4
support autodocs
JReinhold Jul 26, 2023
24f4f66
test duplicate indexers are allowed
JReinhold Jul 26, 2023
18aced2
cleanup
JReinhold Jul 26, 2023
e84041f
use new indexers in stories-json tests
JReinhold Jul 26, 2023
d5cb5e9
extract index tests to separate unit test file
JReinhold Jul 27, 2023
d437d74
Merge branch 'next' of github.com:storybookjs/storybook into indexer-api
JReinhold Jul 27, 2023
a182a0a
Merge branch 'indexer-api' of github.com:storybookjs/storybook into s…
JReinhold Jul 27, 2023
2215a8a
export DeprecatedIndexer
JReinhold Jul 27, 2023
1ed123d
fix type check
JReinhold Jul 27, 2023
52f4aca
revert eslint rule
JReinhold Jul 27, 2023
9c39f22
revert eslint rule
JReinhold Jul 27, 2023
0d5a537
streamline errors to use invariant
JReinhold Jul 27, 2023
f42c31d
Merge pull request #23626 from storybookjs/support-new-indexer
JReinhold Jul 27, 2023
e3b5af6
minor typing fixes
JReinhold Jul 27, 2023
624b061
Merge branch 'indexer-api' into improve-core-server-types
JReinhold Jul 27, 2023
dbd8759
Merge pull request #23632 from storybookjs/improve-core-server-types
JReinhold Jul 29, 2023
0fcdb85
Merge branch 'next' of github.com:storybookjs/storybook into indexer-api
JReinhold Jul 29, 2023
1ecedf5
add __id and metaId to BaseIndexInput
JReinhold Jul 29, 2023
2f8d0af
add stories for custom ids
JReinhold Jul 29, 2023
8246e98
fix tests for new indexer api
JReinhold Jul 29, 2023
7519597
Add parameters.__id handling to CsfFile.parse()
JReinhold Jul 29, 2023
cf7d4cf
improve test titles
JReinhold Jul 29, 2023
2a6ca2e
Merge pull request #23656 from storybookjs/change-indexer-api
JReinhold Jul 30, 2023
dd0e8ae
replace csf indexer
JReinhold Jul 30, 2023
6ea84ef
replace csf indexer in docs snippets
JReinhold Jul 30, 2023
a1e1dd7
handle docsOnly from stories.mdx files
JReinhold Jul 30, 2023
ef230bf
add docsOnly handling to test indexers
JReinhold Jul 30, 2023
d14d936
initial implementation of new server indexer
JReinhold Jul 31, 2023
c0e8da0
add support for meta tags in server indexer
JReinhold Jul 31, 2023
478be95
add yaml to server-webpack5 stories glob, convert page stories to yaml
JReinhold Jul 31, 2023
ebe8038
add autodocs tag to server button stories
JReinhold Jul 31, 2023
06b46b4
Merge branch 'next' of github.com:storybookjs/storybook into indexer-api
JReinhold Jul 31, 2023
5a42303
Merge branch 'indexer-api' of github.com:storybookjs/storybook into r…
JReinhold Jul 31, 2023
21aa490
temporarily disable storyIndexer deprecation notices and docs
JReinhold Jul 31, 2023
e58c240
use actual indexers in StoryIndexGenerator tests
JReinhold Aug 1, 2023
730be27
rename docsOnly tag to stories-mdx-docsOnly
JReinhold Aug 1, 2023
d4538d1
ensure 'stories-mdx' tag
JReinhold Aug 1, 2023
7e94681
concatenate meta+story tags instead of overwriting meta tags
JReinhold Aug 1, 2023
afc9fab
Merge branch 'next' of github.com:storybookjs/storybook into indexer-api
JReinhold Aug 1, 2023
a292fba
Merge branch 'indexer-api' of github.com:storybookjs/storybook into r…
JReinhold Aug 1, 2023
3268dc8
fix index docs snippet
JReinhold Aug 1, 2023
1a14ef6
also concatenate tags in deprecated storyIndexers
JReinhold Aug 1, 2023
98282d3
mark new indexers as experimental
JReinhold Aug 1, 2023
efeaba8
revert docs snippets for indexers
JReinhold Aug 1, 2023
f5a249f
move indexInput generation to CsfFile, remove duplicate tags
JReinhold Aug 2, 2023
2952a90
Merge pull request #23660 from storybookjs/replace-indexers
JReinhold Aug 2, 2023
8f3fbd8
Merge pull request #23676 from storybookjs/new-indexer-experimental
JReinhold Aug 2, 2023
5b44692
Merge branch 'next' of github.com:storybookjs/storybook into indexer-api
JReinhold Aug 3, 2023
a528725
Merge branch 'next' into indexer-api
JReinhold Aug 3, 2023
454e551
Reword makeTitle error
JReinhold Aug 3, 2023
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
50 changes: 28 additions & 22 deletions code/addons/docs/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import remarkSlug from 'remark-slug';
import remarkExternalLinks from 'remark-external-links';
import { dedent } from 'ts-dedent';

import type {
IndexerOptions,
StoryIndexer,
DocsOptions,
Options,
StorybookConfig,
} 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 @@ -135,23 +129,35 @@ async function webpack(
return result;
}

const storyIndexers = (indexers: StoryIndexer[] | null) => {
const mdxIndexer = async (fileName: string, opts: IndexerOptions) => {
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,
},
...(indexers || []),
];
};
const csf = loadCsf(code, { ...opts, fileName }).parse();

const { indexInputs, stories } = csf;

return indexInputs.map((input, index) => {
const docsOnly = stories[index].parameters?.docsOnly;
const tags = input.tags ? input.tags : [];
if (docsOnly) {
tags.push('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 { ...input, tags };
});
},
});

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

const docs = (docsOptions: DocsOptions) => {
return {
Expand All @@ -170,9 +176,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 experimental_indexers, docsX as docs };
2 changes: 1 addition & 1 deletion code/lib/cli/src/generators/SERVER/index.ts
Original file line number Diff line number Diff line change
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
4 changes: 3 additions & 1 deletion code/lib/core-common/src/utils/validate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ const renderers = ['html', 'preact', 'react', 'server', 'svelte', 'vue', 'vue3',

const rendererNames = [...renderers, ...renderers.map((renderer) => `@storybook/${renderer}`)];

export function validateFrameworkName(frameworkName: string | undefined) {
export function validateFrameworkName(
frameworkName: string | undefined
): asserts frameworkName is string {
const automigrateMessage = `Please run 'npx storybook@next automigrate' to automatically fix your config.

See the migration guide for more information:
Expand Down
1 change: 1 addition & 0 deletions code/lib/core-server/package.json
Original file line number Diff line number Diff line change
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
29 changes: 15 additions & 14 deletions code/lib/core-server/src/build-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ export async function buildDevStandalone(
options: CLIOptions & LoadOptions & BuilderOptions
): Promise<{ port: number; address: string; networkAddress: string }> {
const { packageJson, versionUpdates } = options;
const { version } = packageJson;
invariant(version !== undefined, 'Expected package.json version to be defined.');
invariant(
packageJson.version !== undefined,
`Expected package.json#version to be defined in the "${packageJson.name}" package}`
);
// updateInfo are cached, so this is typically pretty fast
const [port, versionCheck] = await Promise.all([
getServerPort(options.port),
versionUpdates
? updateCheck(version)
? updateCheck(packageJson.version)
: Promise.resolve({ success: false, cached: false, data: {}, time: Date.now() }),
]);

Expand All @@ -64,10 +66,9 @@ export async function buildDevStandalone(

const config = await loadMainConfig(options);
const { framework } = config;
invariant(framework, 'framework is required in Storybook v7');
const corePresets = [];

const frameworkName = typeof framework === 'string' ? framework : framework.name;
const frameworkName = typeof framework === 'string' ? framework : framework?.name;
validateFrameworkName(frameworkName);

corePresets.push(join(frameworkName, 'preset'));
Expand All @@ -84,7 +85,8 @@ export async function buildDevStandalone(
});

const { renderer, builder, disableTelemetry } = await presets.apply<CoreConfig>('core', {});
invariant(builder, 'no builder configured!');

invariant(builder, 'No builder configured in core.builder');

if (!options.disableTelemetry && !disableTelemetry) {
if (versionCheck.success && !versionCheck.cached) {
Expand All @@ -98,9 +100,8 @@ export async function buildDevStandalone(
getManagerBuilder(),
]);

const resolvedRenderer = renderer
? resolveAddonName(options.configDir, renderer, options)
: undefined;
const resolvedRenderer = renderer && resolveAddonName(options.configDir, renderer, options);

// Load second pass: all presets are applied in order
presets = await loadAllPresets({
corePresets: [
Expand Down Expand Up @@ -128,10 +129,10 @@ export async function buildDevStandalone(
fullOptions
);

const previewTotalTime = previewResult && previewResult.totalTime;
const managerTotalTime = managerResult ? managerResult.totalTime : undefined;
const previewStats = previewResult && previewResult.stats;
const managerStats = managerResult && managerResult.stats;
const previewTotalTime = previewResult?.totalTime;
const managerTotalTime = managerResult?.totalTime;
const previewStats = previewResult?.stats;
const managerStats = managerResult?.stats;

if (options.webpackStatsJson) {
const target = options.webpackStatsJson === true ? options.outputDir : options.webpackStatsJson;
Expand Down Expand Up @@ -162,7 +163,7 @@ export async function buildDevStandalone(
if (!options.quiet) {
outputStartupInformation({
updateInfo: versionCheck,
version,
version: packageJson.version,
name,
address,
networkAddress,
Expand Down
28 changes: 15 additions & 13 deletions code/lib/core-server/src/build-static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,16 @@ export async function buildStaticStandalone(options: BuildStaticStandaloneOption
...options,
});

const [features, core, staticDirs, storyIndexers, stories, docsOptions] = await Promise.all([
presets.apply<StorybookConfig['features']>('features'),
presets.apply<CoreConfig>('core'),
presets.apply<StorybookConfig['staticDirs']>('staticDirs'),
presets.apply('storyIndexers', []),
presets.apply('stories'),
presets.apply<DocsOptions>('docs', {}),
]);
const [features, core, staticDirs, indexers, deprecatedStoryIndexers, stories, docsOptions] =
await Promise.all([
presets.apply<StorybookConfig['features']>('features'),
presets.apply<CoreConfig>('core'),
presets.apply<StorybookConfig['staticDirs']>('staticDirs'),
presets.apply('experimental_indexers', []),
presets.apply('storyIndexers', []),
presets.apply('stories'),
presets.apply<DocsOptions>('docs', {}),
]);

const fullOptions: Options = {
...options,
Expand Down Expand Up @@ -164,27 +166,27 @@ export async function buildStaticStandalone(options: BuildStaticStandaloneOption
const normalizedStories = normalizeStories(stories, directories);
const generator = new StoryIndexGenerator(normalizedStories, {
...directories,
storyIndexers,
storyIndexers: deprecatedStoryIndexers,
indexers,
docs: docsOptions,
storiesV2Compatibility: !features?.storyStoreV7,
storyStoreV7: !!features?.storyStoreV7,
});

const initializedStoryIndexGeneratorPromise = generator.initialize().then(() => generator);
initializedStoryIndexGenerator = generator.initialize().then(() => generator);
effects.push(
extractStoriesJson(
join(options.outputDir, 'stories.json'),
initializedStoryIndexGeneratorPromise,
initializedStoryIndexGenerator as Promise<StoryIndexGenerator>,
convertToIndexV3
)
);
effects.push(
extractStoriesJson(
join(options.outputDir, 'index.json'),
initializedStoryIndexGeneratorPromise
initializedStoryIndexGenerator as Promise<StoryIndexGenerator>
)
);
initializedStoryIndexGenerator = initializedStoryIndexGeneratorPromise;
}

if (!core?.disableProjectJson) {
Expand Down
24 changes: 9 additions & 15 deletions code/lib/core-server/src/presets/common-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import {
import type {
CLIOptions,
CoreConfig,
IndexerOptions,
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 @@ -195,20 +194,15 @@ export const features = async (
legacyDecoratorFileOrder: false,
});

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

// eslint-disable-next-line @typescript-eslint/naming-convention
export const experimental_indexers: StorybookConfig['experimental_indexers'] = (existingIndexers) =>
[csfIndexer].concat(existingIndexers || []);

export const frameworkOptions = async (
_: never,
options: Options
Expand Down