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

[Bug]: The codemod mdx-to-csf should be an automigration, since Storybook 8 doesn't support stories.mdx files #26131

Closed
Tracked by #25432
valentinpalkovic opened this issue Feb 21, 2024 · 2 comments · Fixed by #26201
Assignees
Milestone

Comments

@valentinpalkovic
Copy link
Contributor

valentinpalkovic commented Feb 21, 2024

In Storybook 8.0, we have removed .stories.mdx support. Therefore, the automigration mdx-to-csf should be enforced during upgrade.

Acceptance criteria

  • The mdx-to-csf codemod should also run as an automigration
  • The user should be notified that the codemod isn't perfect, and the user should recheck the story files after the migration.
@ndelangen
Copy link
Member

Isn't this what the autoblocker is solving already?

@ndelangen
Copy link
Member

@valentinpalkovic I'm thinking that maybe I can refactor this existing automigration to also do the work of migrating the user's stories/.mdx files.

import chalk from 'chalk';
import dedent from 'ts-dedent';
import semver from 'semver';
import type { StoriesEntry } from '@storybook/types';
import { updateMainConfig } from '../helpers/mainConfigFile';
import type { Fix } from '../types';
const logger = console;
export interface BareMdxStoriesGlobRunOptions {
existingStoriesEntries: StoriesEntry[];
nextStoriesEntries: StoriesEntry[];
}
const getNextGlob = (glob: string) => {
// '../src/**/*.stories.@(mdx|js|jsx|ts|tsx)' -> '../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'
const extGlobsRegex = new RegExp(/(.*\.)(stories\.@.*)(\|mdx|mdx\|)(.*)$/i);
if (glob.match(extGlobsRegex)) {
return glob.replace(extGlobsRegex, '$1@(mdx|$2$4)');
}
// '../src/**/*.stories.*' -> '../src/**/*.@(mdx|stories.*)'
const allStoriesExtensionsRegex = new RegExp(/(.*\.)(stories\.\*)$/i);
if (glob.match(allStoriesExtensionsRegex)) {
return glob.replace(allStoriesExtensionsRegex, '$1@(mdx|$2)');
}
// '../src/**/*.stories.mdx' -> '../src/**/*.mdx'
return glob.replaceAll('.stories.mdx', '.mdx');
};
export const bareMdxStoriesGlob: Fix<BareMdxStoriesGlobRunOptions> = {
id: 'bare-mdx-stories-glob',
async check({ storybookVersion, mainConfig }) {
if (!semver.gte(storybookVersion, '7.0.0')) {
return null;
}
const existingStoriesEntries = mainConfig.stories as StoriesEntry[];
if (!existingStoriesEntries) {
throw new Error(dedent`
❌ Unable to determine Storybook stories globs in ${chalk.blue(
mainConfig
)}, skipping ${chalk.cyan(this.id)} fix.
In Storybook 7, we have deprecated defining stories in MDX files, and consequently have changed the suffix to simply .mdx.
We were unable to automatically migrate your 'stories' config to include any .mdx file instead of just .stories.mdx.
We suggest you make this change manually.
To learn more about this change, see: ${chalk.yellow(
'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#mdx-docs-files'
)}
`);
}
const nextStoriesEntries = existingStoriesEntries.map((entry) => {
const isSpecifier = typeof entry !== 'string';
const glob = isSpecifier ? entry.files : entry;
if (!glob) {
// storySpecifier without the 'files' property. Just add the existing to the next list
return entry;
}
const nextGlob = getNextGlob(glob);
return isSpecifier ? { ...entry, files: nextGlob } : nextGlob;
});
// bails if there are no changes
if (
existingStoriesEntries.length === nextStoriesEntries.length &&
existingStoriesEntries.every((entry, index) => {
const nextEntry = nextStoriesEntries[index];
if (typeof entry === 'string') {
return entry === nextEntry;
}
if (typeof nextEntry === 'string') {
return false;
}
return entry.files === nextEntry.files;
})
) {
return null;
}
return { existingStoriesEntries, nextStoriesEntries };
},
prompt({ existingStoriesEntries, nextStoriesEntries }) {
const prettyExistingStoriesEntries = existingStoriesEntries
.map((entry) => JSON.stringify(entry, null, 2))
.join('\n');
const prettyNextStoriesEntries = nextStoriesEntries
.map((entry) => JSON.stringify(entry, null, 2))
.join('\n');
return dedent`
We've detected your project has one or more globs in your 'stories' config that matches .stories.mdx files:
${chalk.cyan(prettyExistingStoriesEntries)}
In Storybook 7, we have deprecated defining stories in MDX files, and consequently have changed the suffix to simply .mdx.
We can automatically migrate your 'stories' config to include any .mdx file instead of just .stories.mdx.
That would result in the following 'stories' config:
${chalk.cyan(prettyNextStoriesEntries)}
To learn more about this change, see: ${chalk.yellow(
'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#mdx-docs-files'
)}
`;
},
async run({ dryRun, mainConfigPath, result: { nextStoriesEntries } }) {
logger.info(dedent`✅ Setting 'stories' config:
${JSON.stringify(nextStoriesEntries, null, 2)}`);
if (!dryRun) {
await updateMainConfig({ mainConfigPath, dryRun: !!dryRun }, async (main) => {
main.setFieldValue(['stories'], nextStoriesEntries);
});
}
},
};

WDYT?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

2 participants