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

MDX2: Add automigration for GFM support #20091

Closed
shilman opened this issue Dec 5, 2022 · 36 comments · Fixed by #21186
Closed

MDX2: Add automigration for GFM support #20091

shilman opened this issue Dec 5, 2022 · 36 comments · Fixed by #21186

Comments

@shilman
Copy link
Member

shilman commented Dec 5, 2022

Is your feature request related to a problem? Please describe

One of the breaking changes from MDX1 to MDX2 is lack of Github-flavored markdown (GFM) support. This will break a lot of SB users as they upgrade.

Describe the solution you'd like

We could add GFM by default in Storybook, but we're trying to get away from doing magic stuff and get as close to "standard MDX2" as possible.

Therefore, we should have an automigration that asks whether you want to add GFM support and updates your configuration accordingly.

Here's an example in a real project:

// main.js
{
  addons: [{
    name: @storybook/addon-docs’,
    options: {
      mdxCompileOptions: {
        remarkPlugins: [remarkGfm],
      },
    }
  }]
};

Describe alternatives you've considered

Just setting the defaults to support GFM

Are you able to assist to bring the feature to reality?

yes, I can

Additional context

No response

@Kwooda
Copy link

Kwooda commented Dec 16, 2022

I've been struggling for days, trying to figure out how to enable GFM with MDX2. If nothing else, there should be a simple example of how to do this in the docs. It's extraordinarily frustrating.

@ndelangen
Copy link
Member

I'd imagine that:

  • add remark-gfm as a dep
  • add @storybook/addon-docs as a dep
  • add the following to your list of addons in main.js:
{
    name: ‘@storybook/addon-docs’,
    options: {
      mdxCompileOptions: {
        remarkPlugins: [remarkGfm],
      },
    }
  }

... that should do it? @Kwooda ?

@ndelangen
Copy link
Member

@shilman I tried writing the automigration code, and due to the flexibility of main.js it's really hard.

It can be ESM or CJS, TypeScript of Plain javascript, it can have 1 default export, or a bunch of named exports.. and can technically even export a function a default.

AFAIK we do not have a reliable way of getting/setting this, which would allow me to add runtime-code to the file.

I need to add an import/require statement, and I need to add a function invocation.

It's not impossible, but I am convinced it's going to be way way waaay easier to add this to the user's main.js using the existing methods:

module.exports = {
   addons: [@storybook/addon-gfm']
 };

And this new addon is responsible for depending on the package, and injecting it in the proper place in the preset-chain.

It might make it less transparent for the user.. I'm not sure which one is truly more important? easy of migration or easy of modification after?

Depending on which one we prioritize, we either: write the migration OR we improve docs..
We could do a bit of a mix, where we ask users to do a manual migration?

@Kwooda
Copy link

Kwooda commented Dec 16, 2022

@ndelangen I tried that and it doesn't know what remarkGfm is.

@ndelangen
Copy link
Member

Yeah, you'd have to import/require the module..

here's the recipe:

// .storybook/main.js
const remarkGfm = require('remark-gfm');
module.exports = {
stories: ['../src/**/*.stories.@(js|ts)'],
addons: [
// Other addons go here
{
name: '@storybook/addon-docs',
options: {
mdxCompileOptions: {
remarkPlugins: [remarkGfm],
},
},
},
],
framework: {
// Replace your-framework with the name of your framework (e.g., react-webpack5, vue3-webpack5)
name: '@storybook/your-framework',
options: {},
},
docs: {
docsPage: true,
},
};
```

@Kwooda
Copy link

Kwooda commented Dec 16, 2022

It's ESM only and won't let me include it that way. And I can't use an import there, either, as it complains that I can't use it outside of a module.

import remarkGfm from 'remark-gfm'

@ndelangen
Copy link
Member

@shilman looks like making the preset is pretty much required then..

@shilman
Copy link
Member Author

shilman commented Dec 17, 2022

@ndelangen I'm not sure that's true. I have it working in the mdx2-csf repo example Storybook. Granted I'm not doing any CJS stuff there like storyshots. Let's discuss on Monday?

@ndelangen
Copy link
Member

We talked about it and we need to create a documentation-page about MDX guide.

One of the items on that page needs to be about how to add GFM to storybook.

The auto-migration fro mdx1-to-csf needs to be updated to notify users to go to that page, and for what reasons.

@ndelangen
Copy link
Member

@Kwooda The code I linked to isn't ESM, it's CommonJS.

I can't know what "it" refers to when you say:

as it complains that I can't use it outside of a module.

Perhaps it helps if you rename main.js to main.cjs? I do not know your project.

@Kwooda
Copy link

Kwooda commented Dec 19, 2022

@ndelangen when I use require in main.js, I get this message:

const remarkGfm = require('remark-gfm'); 
                  ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/tkmafa3/projects/designsystem/kds-web-core/node_modules/remark-gfm/index.js from /Users/tkmafa3/projects/designsystem/kds-web-core/.storybook/main.js not supported.
Instead change the require of index.js in /Users/tkmafa3/projects/designsystem/kds-web-core/.storybook/main.js to a dynamic import() which is available in all CommonJS modules.

When I try to use import, I get this message:

/Users/tkmafa3/projects/designsystem/kds-web-core/.storybook/main.js:2
import remarkGfm from 'remark-gfm'
^^^^^^

SyntaxError: Cannot use import statement outside a module

@joshwooding
Copy link
Contributor

@Kwooda Could you try using the import and changing main.js to main.mjs ?

@ndelangen
Copy link
Member

Looks like the new version is ESM only @shilman

@Kwooda
Copy link

Kwooda commented Dec 19, 2022

@joshwooding I get the same errors:

ERR! Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/tkmafa3/projects/designsystem/kds-web-core/.storybook/main.mjs not supported.

Except I don't know why it's complaining about require() since I am using import.

import remarkGfm from 'remark-gfm'

@joshwooding
Copy link
Contributor

joshwooding commented Dec 19, 2022

@Kwooda Ah, it's the import of the main.mjs file in the storybook code that's erroring there. Just curious what version of Storybook are you testing this with?

@Kwooda
Copy link

Kwooda commented Dec 19, 2022

@joshwooding I am using version 6.5.14

@joshwooding
Copy link
Contributor

Ah, ESM support came in an early v7 alpha.

@Kwooda
Copy link

Kwooda commented Dec 19, 2022

Is there a way to make GFM work with MDX2 in 6.5.14, or do I need to wait until version 7 comes out?

@justintemps
Copy link

justintemps commented Dec 27, 2022

@ndelangen, @joshwooding I tried this with esm in storybook@7.0.0-beta.13 and still couldn't get it to work.

// .storybook/main.mjs
import remarkGfm from "remark-gfm";

...

export const addons = [
  "@storybook/addon-links",
  {
    name: "@storybook/addon-docs",
    options: {
      mdxCompileOptions: {
        remarkPlugins: [remarkGfm],
      },
    },
  },
  {
    name: "@storybook/preset-create-react-app",
    options: {
      scriptsPackageName: "react-scripts",
    },
  },
  "@storybook/addon-postcss",
];

...

No error messages, it just doesn't render tables like I expected. Am I doing something wrong here?

@ndelangen
Copy link
Member

@justintemps would you happen to have a repro for me to debug?

@justintemps
Copy link

@ndelangen fair enough! Will put one together as soon as I get a chance.

@htmlin
Copy link

htmlin commented Jan 11, 2023

The solution here does not work under the @storybook/react-vite framework

storybook/docs/snippets/common/storybook-main-config-remark-options.js.mdx

Copy link
Member Author

shilman commented Jan 11, 2023

I think it's fixed by #20116 ... will try to get that merged ASAP

@htmlin
Copy link

htmlin commented Jan 11, 2023

I think it's fixed by #20116 ... will try to get that merged ASAP

It looks good.

@markpalfreeman
Copy link

markpalfreeman commented Feb 3, 2023

I'm still having issues with the @storybook/web-components-vite framework as well (on beta.41) using the recommended manual configuration to addon-docs. Expected tables are still rendered as plain text.

@shilman
Copy link
Member Author

shilman commented Feb 4, 2023

@markpalfreeman can you share your project, or at least your main.js config?

@jameschensmith
Copy link

@markpalfreeman, not sure if this helps, but I just ran into this issue today. Make sure your plugin is under mdxPluginOptions.mdxCompileOptions.remarkPlugins, and not mdxCompileOptions.remarkPlugins or mdxPluginOptions.remarkPlugins. That messed me up a bit 🥴

{
  name: "@storybook/addon-docs",
  options: {
    mdxPluginOptions: {
      mdxCompileOptions: {
        remarkPlugins: [remarkGfm],
      },
    },
  },
},

@ndelangen
Copy link
Member

Thank you for that comment @jameschensmith

@markpalfreeman
Copy link

markpalfreeman commented Feb 7, 2023

🤯 @jameschensmith that works! Thanks, I think the docs need to be tweaked to match.

As a slight aside, I get this console message (twice) from the dev server, but the plugin seems to render the GFM features as expected:

info Found existing addon {"name":"@storybook/addon-docs","options":{"mdxPluginOptions":{"mdxCompileOptions":{"remarkPlugins":[null]}}}}, skipping.

Here's my main.ts file:

import type { StorybookConfig } from '@storybook/web-components-vite';
import rootConfig from '../../../../.storybook/main';
import remarkGfm from 'remark-gfm';

const config: StorybookConfig = {
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/addon-a11y',
    {
      name: '@storybook/addon-docs',
      options: {
        mdxPluginOptions: {
          mdxCompileOptions: {
            remarkPlugins: [remarkGfm]
          }
        }
      }
    }
  ],
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|ts)'],
  framework: {
    name: '@storybook/web-components-vite',
    options: {}
  }
};

export default config;

@jameschensmith
Copy link

jameschensmith commented Feb 7, 2023

@markpalfreeman, yeah, I think you might also need to disable docs from the essentials add-on (snippet highly truncated):

export default {
  addons: [
    {
      name: "@storybook/addon-essentials",
      options: {
        docs: false,
      },
    },
    {
      name: "@storybook/addon-docs",
      options: {
        mdxPluginOptions: {
          mdxCompileOptions: {
            remarkPlugins: [remarkGfm],
          },
        },
      },
    },
  ],
};

@shilman
Copy link
Member Author

shilman commented Feb 24, 2023

Huzzah!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-beta.54 containing PR #21186 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb@next upgrade --prerelease

@starsoul666
Copy link

@markpalfreeman, yeah, I think you might also need to disable docs from the essentials add-on (snippet highly truncated):

export default {
  addons: [
    {
      name: "@storybook/addon-essentials",
      options: {
        docs: false,
      },
    },
    {
      name: "@storybook/addon-docs",
      options: {
        mdxPluginOptions: {
          mdxCompileOptions: {
            remarkPlugins: [remarkGfm],
          },
        },
      },
    },
  ],
};

I tested this configuration under @storybook/react-webpack5, but it didn't work. The tables in the mdx file were not rendered.

{ name: '@storybook/addon-docs', options: { mdxPluginOptions: { mdxCompileOptions: { remarkPlugins: [remarkGfm] } } } }

@storybook/addon-docs@7.0.7

@diego-musa
Copy link

I also not getting the same results in a table test.

    "@storybook/addon-styling": "1.0.8",
    "@storybook/addon-actions": "7.0.11",
    "@storybook/addon-essentials": "7.0.11",
    "@storybook/addon-interactions": "7.0.11",
    "@storybook/addon-links": "7.0.11",
    "@storybook/addons": "7.0.11",
    "@storybook/builder-vite": "7.0.11",
    "@storybook/react": "7.0.11",
    "@storybook/react-vite": "7.0.11",
    "@storybook/testing-library": "0.1.0",
    "@vitejs/plugin-react": "4.0.0",
    "remark-gfm": "3.0.1",
    "storybook": "7.0.11",
import remarkGfm from 'remark-gfm';

export default {
  "stories": ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  "addons": ["@storybook/addon-links", "@storybook/addon-essentials", "@storybook/addon-interactions", "@storybook/addon-styling", {
    name: "@storybook/addon-essentials",
    options: {
      docs: false,
    },
  }, {
      name: '@storybook/addon-docs',
      options: {
        mdxPluginOptions: {
          mdxCompileOptions: {
            remarkPlugins: [remarkGfm],
          },
        },
      },
    }],
» npm run storybook

> my-project@0.0.0 storybook
> storybook dev -p 6006

@storybook/cli v7.0.11

info Found existing addon {"name":"@storybook/addon-docs","options":{"mdxPluginOptions":{"mdxCompileOptions":{"remarkPlugins":[{}]}}}}, skipping.
info Found existing addon {"name":"@storybook/addon-docs","options":{"mdxPluginOptions":{"mdxCompileOptions":{"remarkPlugins":[{}]}}}}, skipping.
info => Starting manager..
╭────────────────────────────────────────────────────╮
│                                                    │
│   Storybook 7.0.11 for react-vite started          │
│   814 ms for manager and 2.92 s for preview        │
│                                                    │
│    Local:            http://localhost:6006/        │
│    On your network:  http://192.168.2.152:6006/    │
│                                                    │
╰────────────────────────────────────────────────────╯
# Welcome to Storybook

Table test

| a | b | c |
| 1 | 2 | 3 |

Storybook helps you build UI components in isolation from your app's business logic, data, and context.
Screenshot 2023-05-15 at 14 16 10

@mayerraphael
Copy link

mayerraphael commented Jun 12, 2023

Edit: My bad worked after migrating from requirejs to esm.

@terrymun
Copy link

Are there any plans to support remark-gfm@4?

@ADTC
Copy link

ADTC commented Jan 17, 2024

migrating from requirejs to esm.

@mayerraphael how did you do that?

Edit: it's done by replacing require with import, and changing the module.exports to a const that is exported as default:

import remarkGfm from 'remark-gfm';

// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    // Other addons go here
    {
      name: '@storybook/addon-docs',
      options: {
        mdxPluginOptions: {
          mdxCompileOptions: {
            remarkPlugins: [remarkGfm],
          },
        },
      },
    },
  ],
};

export default config;

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

Successfully merging a pull request may close this issue.