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

Addon-docs: Add legacy transitional support for MDX1 #20747

Merged
merged 9 commits into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 28 additions & 3 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
- [ArgsTable block](#argstable-block)
- [Configuring Autodocs](#configuring-autodocs)
- [MDX2 upgrade](#mdx2-upgrade)
- [Legacy MDX1 support](#legacy-mdx1-support)
- [Default docs styles will leak into non-story user components](#default-docs-styles-will-leak-into-non-story-user-components)
- [Explicit `<code>` elements are no longer syntax highlighted](#explicit-code-elements-are-no-longer-syntax-highlighted)
- [Dropped source loader / storiesOf static snippets](#dropped-source-loader--storiesof-static-snippets)
Expand Down Expand Up @@ -978,11 +979,35 @@ export const MyDocsContainer = (props) => (

Storybook 7 Docs uses MDXv2 instead of MDXv1. This means an improved syntax, support for inline JS expression, and improved performance among [other benefits](https://mdxjs.com/blog/v2/).

If you use `.stories.mdx` files in your project, you may need to edit them since MDX2 contains [breaking changes](https://mdxjs.com/migrating/v2/#update-mdx-files).
If you use `.stories.mdx` files in your project, you'll probably need to edit them since MDX2 contains [breaking changes](https://mdxjs.com/migrating/v2/#update-mdx-files). In general, MDX2 is stricter and more structured than MDX1.

We will update this section with specific pointers based on user feedback during the prerelease period and probably add an codemod to help streamline the upgrade before final 7.0 release.
We've provided an automigration, `mdx1to2` that makes a few of these changes automatically. For example, `mdx1to2` automatically converts MDX1-style HTML comments into MDX2-style JSX comments to save you time.

As part of the upgrade we deleted the codemod `mdx-to-csf` and will be replacing it with a more sophisticated version prior to release.
Unfortunately, the set of changes from MDX1 to MDX2 is vast, and many changes are subtle, so the bulk of the migration will be manual. You can use the [MDX Playground](https://mdxjs.com/playground/) to try out snippets interactively.

#### Legacy MDX1 support

If you get stuck with the [MDX2 upgrade](#mdx2-upgrade), we also provide opt-in legacy MDX1 support. This is intended as a temporary solution while you upgrade your Storybook; MDX1 will be discontinued in Storybook 8.0. The MDX1 library is no longer maintained and installing it results in `npm audit` security warnings.

To process your `.stories.mdx` files with MDX1, first install the `@storybook/mdx1-csf` package in your project:

```
yarn add -D @storybook/mdx1-csf@next
```

Then enable the `legacyMdx1` feature flag in your `.storybook/main.js` file:

```js
export default {
features: {
legacyMdx1: true,
}
}
```

NOTE: This only affects `.(stories|story).mdx` files. Notably, if you want to use Storybook 7's "pure" `.mdx` format, you'll need to use MDX2 for that.

NOTE: Legacy MDX1 support is only for Webpack projects. There is currently no legacy support for Vite.

#### Default docs styles will leak into non-story user components

Expand Down
6 changes: 6 additions & 0 deletions code/addons/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,15 @@
"typescript": "~4.9.3"
},
"peerDependencies": {
"@storybook/mdx1-csf": ">=1.0.0-0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"peerDependenciesMeta": {
"@storybook/mdx1-csf": {
"optional": true
}
},
"publishConfig": {
"access": "public"
},
Expand Down
13 changes: 11 additions & 2 deletions code/addons/docs/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { dedent } from 'ts-dedent';
import type { IndexerOptions, StoryIndexer, DocsOptions, Options } from '@storybook/types';
import type { CsfPluginOptions } from '@storybook/csf-plugin';
import type { JSXOptions } from '@storybook/mdx2-csf';
import { global } from '@storybook/global';
import { loadCsf } from '@storybook/csf-tools';
import { logger } from '@storybook/node-logger';
import { ensureReactPeerDeps } from './ensure-react-peer-deps';

async function webpack(
Expand Down Expand Up @@ -73,7 +75,12 @@ async function webpack(
`);
}

const mdxLoader = require.resolve('@storybook/mdx2-csf/loader');
const mdxVersion = global.FEATURES?.legacyMdx1 ? 'MDX1' : 'MDX2';
logger.info(`Addon-docs: using ${mdxVersion}`);

const mdxLoader = global.FEATURES?.legacyMdx1
? require.resolve('@storybook/mdx1-csf/loader')
: require.resolve('@storybook/mdx2-csf/loader');

let rules = module.rules || [];
if (transcludeMarkdown) {
Expand Down Expand Up @@ -135,7 +142,9 @@ async function webpack(
const storyIndexers = (indexers: StoryIndexer[] | null) => {
const mdxIndexer = async (fileName: string, opts: IndexerOptions) => {
let code = (await fs.readFile(fileName, 'utf-8')).toString();
const { compile } = await import('@storybook/mdx2-csf');
const { compile } = global.FEATURES?.legacyMdx1
? await import('@storybook/mdx1-csf')
: await import('@storybook/mdx2-csf');
code = await compile(code, {});
return loadCsf(code, { ...opts, fileName }).parse();
};
Expand Down
11 changes: 11 additions & 0 deletions code/addons/docs/src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@ declare module 'remark-external-links';
declare module 'babel-plugin-react-docgen';
declare module 'acorn-jsx';
declare module 'vue/dist/vue';
declare module '@storybook/mdx1-csf';

declare module 'sveltedoc-parser' {
export function parse(options: any): Promise<any>;
}

declare var FEATURES:
| {
storyStoreV7?: boolean;
interactionsDebugger?: boolean;
breakingChangesV7?: boolean;
argTypeTargetsV7?: boolean;
legacyMdx1?: boolean;
}
| undefined;

declare var LOGLEVEL: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent' | undefined;
1 change: 1 addition & 0 deletions code/lib/core-server/src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ declare var FEATURES:
interactionsDebugger?: boolean;
breakingChangesV7?: boolean;
argTypeTargetsV7?: boolean;
legacyMdx1?: boolean;
}
| undefined;
1 change: 1 addition & 0 deletions code/lib/preview-api/src/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ declare var FEATURES:
interactionsDebugger?: boolean;
breakingChangesV7?: boolean;
argTypeTargetsV7?: boolean;
legacyMdx1?: boolean;
}
| undefined;

Expand Down
5 changes: 5 additions & 0 deletions code/lib/types/src/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,11 @@ export interface StorybookConfig {
* Will be removed in 7.0.
*/
warnOnLegacyHierarchySeparator?: boolean;

/**
* Use legacy MDX1, to help smooth migration to 7.0
*/
legacyMdx1?: boolean;
};

/**
Expand Down
4 changes: 4 additions & 0 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5206,8 +5206,12 @@ __metadata:
ts-dedent: ^2.0.0
typescript: ~4.9.3
peerDependencies:
"@storybook/mdx1-csf": ">=1.0.0-0"
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@storybook/mdx1-csf":
optional: true
languageName: unknown
linkType: soft

Expand Down