Describe the bug
After upgrading Storybook to 5.3.0-rc.8 in my Vue application and try to migrate my stories to only MDX, the 'Docs' tab returns ReferenceError: "h is not defined"
To Reproduce
Steps to reproduce the behavior:
stories: ['../src/components/**/*.stories.(js|mdx)'],
import { Meta, Story, Props } from '@storybook/addon-docs/blocks';
import { text, withKnobs } from '@storybook/addon-knobs';
import ZIcon from '../z-icon';
<Meta
title='Icon'
component={ZIcon}
decorators={[withKnobs]}
/>
<Story name='normal'>
{{
components: {ZIcon},
template: `<ZIcon :icon="['fab', 'cc-visa']" icon-size="larger"/>`,
}}
</Story>
## Props
<Props of={ZIcon} />
npm run storybook;Expected behavior
Docs works with MDX fully support in Vue.
Screenshots

Code snippets
z-icon.stories.mdx generated when Storybook is running:
import React from 'react'
import { mdx } from '@mdx-js/react'
/* @jsx mdx */
import { assertIsFn, AddContext } from "@storybook/addon-docs/blocks";
import { Meta, Story, Props } from '@storybook/addon-docs/blocks';
import { text, withKnobs } from '@storybook/addon-knobs';
import ZIcon from '../z-icon';
const makeShortcode = name => function MDXDefaultShortcode(props) {
console.warn("Component " + name + " was not imported, exported, or provided by MDXProvider as global scope")
return <div {...props}/>
};
const layoutProps = {
};
const MDXLayout = "wrapper"
function MDXContent({
components,
...props
}) {
return <MDXLayout {...layoutProps} {...props} components={components} mdxType="MDXLayout">
<Meta title='Icon' component={ZIcon} decorators={[withKnobs]} mdxType="Meta" />
<Story name='normal' mdxType="Story">
{{
components: {
ZIcon
},
template: `<ZIcon :icon="['fab', 'cc-visa']" icon-size="larger"/>`
}}
</Story>
<h2 {...{
"id": "props"
}}>{`Props`}</h2>
<Props of={ZIcon} mdxType="Props" />
</MDXLayout>;
}
;
MDXContent.isMDXComponent = true;
export const normal = () => (
{
components: {
ZIcon
},
template: `<ZIcon :icon="['fab', 'cc-visa']" icon-size="larger"/>`
}
);
normal.story = {};
normal.story.name = 'normal';
normal.story.parameters = { mdxSource: '{\n components: {\n ZIcon\n },\n template: `<ZIcon :icon=\"[\'fab\', \'cc-visa\']\" icon-size=\"larger\"/>`\n}' };
const componentMeta = { title: 'Icon', decorators: [withKnobs], includeStories: ["normal"], };
const mdxStoryNameToKey = {"normal":"normal"};
componentMeta.parameters = componentMeta.parameters || {};
componentMeta.parameters.docs = {
...(componentMeta.parameters.docs || {}),
page: () => <AddContext mdxStoryNameToKey={mdxStoryNameToKey} mdxComponentMeta={componentMeta}><MDXContent /></AddContext>,
};
export default componentMeta;
System:
System:
OS: macOS 10.15
CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
Binaries:
Node: 10.15.3 - ~/.nvm/versions/node/v10.15.3/bin/node
Yarn: 1.19.0 - /usr/local/bin/yarn
npm: 6.12.0 - ~/.nvm/versions/node/v10.15.3/bin/npm
Browsers:
Chrome: 79.0.3945.88
Firefox: 71.0
Safari: 13.0.2
npmPackages:
@storybook/addon-a11y: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/addon-actions: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/addon-docs: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/addon-knobs: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/addon-links: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/addon-storysource: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/addon-viewport: ^5.2.8 => 5.2.8
@storybook/addons: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/cli: ^5.3.0-rc.8 => 5.3.0-rc.8
@storybook/vue: ^5.3.0-rc.8 => 5.3.0-rc.8
npmGlobalPackages:
@storybook/cli: 5.3.0-rc.8
Additional context
Add any other context about the problem here.
@danilovaz Please take a look at this issue, which AFAIK has a workaround: https://github.com/storybookjs/storybook/issues/8096
@Aaron-Pool should we update the documentation for this? Or is there a code change required? Thanks!
@shilman depends on whether you think it's worth adding documentation for a (possibly temporary) work around 🤷♂️
@shilman I greatly appreciate your help. I had already followed the steps of the issue you commented on, even tried again now. But the same bug persists in this RC version, it is not possible to use only stories.mdx and another downside is that every Vue Component I need to register globally in preview.js otherwise it just does not work to import a Vue Component to my story.
I tried to follow this: https://github.com/trevoreyre/storybook-mdx-vue-example (which uses addon-docs beta22) but does'nt works too.
@danilovaz sorry about the hassle. Unfortunately, I'm still pretty ignorant on the vue side of things.. @Aaron-Pool any thoughts?
@shilman No need to apologize. I really appreciate the help. I will create a repository to explore the problem in isolation and share here with you.
@danilovaz if you could even simply fork the example repo you linked to, and get it to your "broken" state, that would be great to help us debug 👌
@Aaron-Pool @shilman Really appreciate the attention and help. I found the problem with my project while trying to isolate an example. We have a babel.config.js and this config was overriding the workaround suggested. So I have to add jsx: false in my babel.config.js and in webpack.config.js
If you allow me a suggestion. Would it be possible in the future to use the Vue components in the Storybook without having to declare each in preview.js? I have to do this:
import ComponentA from '../src/components/component-a/component-a.vue';
import ComponentB from '../src/components/component-b/component-.bvue';
import ComponentC from '../src/components/component-c/component-c.vue';
import ComponentD from '../src/components/component-d/component-d.vue';
Vue.component('ComponentA', ComponentA);
Vue.component('ComponentB', ComponentB);
Vue.component('ComponentC', ComponentC);
Vue.component('ComponentD', ComponentD);
@danilovaz that shouldn't be the case... You should be able to declare your components locally, just like you can in a Vue app. What kind of setup do you have that isn't working?
@Aaron-Pool If I don't register components in preview.js then I receive this error in console for each component when run Storybook:
[Vue warn]: Unknown custom element: <ZHeader> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
My configurations in .storybook
main.js
module.exports = {
addons: [
'@storybook/addon-docs',
'@storybook/addon-storysource',
'@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addon-knobs',
'@storybook/addon-viewport',
'@storybook/addon-a11y',
],
stories: ["../src/**/*.stories.(mdx)"],
// Modify webpack to remove babel-preset-vue from .mdx loaders
webpack: async config => {
const rules = config.module.rules;
const mdxRules = rules.filter(
filterRules([/\.mdx$/, /\.(stories|story).mdx$/])
);
let [jsxRule] = rules.filter(filterRules([/\.(mjs|jsx?)$/]));
mdxRules.forEach(mdxRule => {
const [babelLoader] = mdxRule.use.filter(
({ loader }) => loader === "babel-loader"
);
babelLoader.options.presets = babelLoader.options.presets.filter(
preset => !preset.includes("babel-preset-vue")
);
});
const [babelLoader] = jsxRule.use.filter(({ loader }) => loader === 'babel-loader')
babelLoader.options = {
cacheDirectory: path.resolve(__dirname, '..', 'node_modules', '.cache', 'storybook'),
presets: ['@vue/app'],
babelrc: false
}
return config;
}
};
manager.js
import { addons } from '@storybook/addons';
import { create } from '@storybook/theming/create';
const theme = create({
base: 'light',
brandTitle: 'My custom title',
});
addons.setConfig({
showRoots: true,
showPanel: true,
sortStoriesByKind: true,
panelPosition: 'bottom',
theme,
});
preview.js
```js
import Vue from 'vue';
import { addDecorator, addParameters } from '@storybook/vue';
import { withA11y } from '@storybook/addon-a11y';
import { withKnobs } from '@storybook/addon-knobs';
import ComponentA from '../src/components/component-a/component-a.vue';
import ComponentB from '../src/components/component-b/component-.bvue';
import ComponentC from '../src/components/component-c/component-c.vue';
import ComponentD from '../src/components/component-d/component-d.vue';
Vue.component('ComponentA', ComponentA);
Vue.component('ComponentB', ComponentB);
Vue.component('ComponentC', ComponentC);
Vue.component('ComponentD', ComponentD);
addDecorator(withA11y)
addDecorator(
withKnobs({
escapeHTML: false,
}),
)
addParameters({
docs: {
inlineStories: true,
iframeHeight: '60px',
},
})
Could you show me the actual story that is throwing the error?
@Aaron-Pool Yes of course. This is one of the stories I have, I only removed private information but in general this is the structure:
z-caption.stories.mdx
import { Meta, Preview, Story, Props } from '@storybook/addon-docs/blocks';
import { radios, text, withKnobs } from '@storybook/addon-knobs';
import ZCaption from '../z-caption';
import PatternStatus from '../../utils/pattern-status';
<Meta title="Caption" component={ZCaption} />
# Caption
<Story name="status">
{{
template: `
<div>
<PatternStatus
:designVersion="{
link: '#',
title: 'ver2019.10.12',
}"
release="November 20, 2019"
pattern="Caption"
/>
</div>
`
}}
</Story>
## Import
```js
import { ZCaption } from "XYZ";
```
## Usage
```
export default {
components: {
ZCaption,
},
}
```
```
{{
template:
<ZCaption>
Caption
</ZCaption>
}}
8 colors are supported.
{{
template:
<div>
<ZCaption color="strong">Strong</ZCaption>
<ZCaption color="soft">Soft</ZCaption>
<ZCaption color="interactive">Interactive</ZCaption>
<ZCaption color="inverted">Inverted</ZCaption>
<ZCaption color="success">Success</ZCaption>
<ZCaption color="danger">Danger</ZCaption>
<ZCaption color="warning">Warning</ZCaption>
<ZCaption color="info">Info</ZCaption>
</div>
}}
3 aligns are supported.
{{
template:
<div>
<ZCaption tag="p" align="left">Left</ZCaption>
<ZCaption tag="p" align="center">Center</ZCaption>
<ZCaption tag="p" align="right">Right</ZCaption>
</div>
}}
We also can pass different tags to represent ZCaption.
You can pass any HTML tags, but try to only use tags that have textual semantics: https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element#Sem%C3%A2nticas_textuais_inline
{{
template: <ZCaption tag="p">Caption</ZCaption>
}}
Experiment with this story with Knobs addon in Canvas mode.
props: {
tag: {
type: String,
default: text('Tag HTML', 'strong'),
},
align: {
type: String,
default: radios(
'Align',
{
left: 'left',
center: 'center',
right: 'right',
},
'left'
),
},
color: {
type: String,
default: radios(
'Color',
{
default: 'inherit',
strong: 'strong',
soft: 'soft',
interactive: 'interactive',
inverted: 'inverted',
success: 'success',
danger: 'danger',
warning: 'warning',
info: 'info',
},
'inherit'
),
}
},
template:
<ZCaption
:tag="tag"
:align="align"
:color="color"
>
Caption
</ZCaption>
}}
@danilovaz Yeah, so the problem here is that the content of each <Story> tag in MDX is itself a component. So, if you want to use a component locally, rather than globally registered, you need to register it in the story component with components: { ZCaption } (assuming you have imported the component in the file.
Or have you already tried that?
@Aaron-Pool You are absolutely right. In some of my tests I must have forgotten to set the Components property.
I really appreciate the support and patience from both of you.
Edited:
Now it's works 🎉