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: Simplest MDX not working @vue/cli app #8096

Closed
margielm opened this issue Sep 16, 2019 · 29 comments
Closed

Addon-docs: Simplest MDX not working @vue/cli app #8096

margielm opened this issue Sep 16, 2019 · 29 comments

Comments

@margielm
Copy link

Describe the bug
After upgrading to [email protected] and adding MDX support to a Vue application created with @Vue/cli - the doc tab is is throwing following error:

h is not defined
ReferenceError: h is not defined
    at container (http://localhost:6006/main.831d3d75a097f0e9391d.bundle.js:667:5)
    at renderWithHooks (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:83540:18)
    at mountIndeterminateComponent (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:85774:13)
    at beginWork$1 (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:86918:16)
    at HTMLUnknownElement.callCallback (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:68779:14)
    at Object.invokeGuardedCallbackDev (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:68829:16)
    at invokeGuardedCallback (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:68886:31)
    at beginWork$$1 (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:91649:7)
    at performUnitOfWork (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:90640:12)
    at workLoopSync (http://localhost:6006/vendors~main.831d3d75a097f0e9391d.bundle.js:90617:22)

To Reproduce
Steps to reproduce the behavior:

  1. create an application using @vue/cli
  2. initalize storybook with
  3. add @storybook/addon-docs -> yarn add @storybook/[email protected] --dev
  4. register addon in addons.js
  5. register addon-docs presets in presets.js
  6. adjust config.js to load mdx files
  7. Add simple MDX file:
import { Story, Meta } from '@storybook/addon-docs/blocks';

<Meta title="Addon|Docs" />

<Story name="test">
  {{
    template: '<div>Hello World</div>',
  }}
</Story>

  1. start storybook
  2. click on Addon|Docs/test story and go to Docs tab
  3. see the error

Expected behavior
To see the documentation page

Screenshots
image

Code snippets
https://github.com/margielm/sb-test
https://github.com/margielm/sb-test/blob/master/stories/hello.stories.mdx

System:
System:
OS: macOS 10.14.6
CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
Binaries:
Node: 12.10.0 - /usr/local/bin/node
Yarn: 1.17.3 - /usr/local/bin/yarn
npm: 6.11.3 - /usr/local/bin/npm
Browsers:
Chrome: 76.0.3809.132
Firefox: 67.0
Safari: 12.1.2
npmPackages:
@storybook/addon-actions: ^5.2.0 => 5.2.0
@storybook/addon-docs: 5.2.0 => 5.2.0
@storybook/addon-links: ^5.2.0 => 5.2.0
@storybook/addons: ^5.2.0 => 5.2.0
@storybook/vue: ^5.2.0 => 5.2.0

@shilman
Copy link
Member

shilman commented Sep 16, 2019

@Aaron-Pool any idea what's going on here?

@Aaron-Pool
Copy link
Contributor

Aaron-Pool commented Sep 17, 2019

Looks like the Vue babel preset is trying to run on .mdx files, and it's trying to parse the jsx but it can't find a Vue create element method (a.k.a, h).

@margielm, make sure that whatever Babel config is including the Vue preset isn't running on MDX files. The docs preset should be sufficient to handle transpiring the MDX files.

If you could post your vue.config.js file I could probably be more specific.

@alexkcollier
Copy link

I'm experiencing the same issue.

vue.config.js

const sharedConf = require('./config/shared-webpack-conf')

module.exports = {
  productionSourceMap: false,
  lintOnSave: true,
  pluginOptions: {
    stylelint: {
      formatter: () => require('prettier'),
    },
    'style-resources-loader': sharedConf.styleResourcesLoaderOptions,
  },
  css: {
    extract: true,
  },
  configureWebpack: {
    resolve: {
      alias: sharedConf.aliases,
    },
  },
}

babel.config.js

module.exports = (api) => {
  api.cache(true)

  return {
    presets: ['@vue/app', '@babel/preset-env'],
    plugins: ['transform-vue-jsx', '@babel/plugin-transform-runtime'],
  }
}

@Aaron-Pool
Copy link
Contributor

Aaron-Pool commented Sep 17, 2019

@alexkcollier, you have a lot of duplicate things in your Babel config, @vue/app is a super set of @babel/preset-env. So you should get rid of preset-env. Additionally, the @vue/app preset contains the @vue/jsx preset, so you should be able to remove the transform-vue-jsx plugin as well.

And, like I said to @margielm, make sure that no Vue loaders are running on mdx files. The only loaders running on mdx file types should be provided by the docs preset. If you let the Vue preset run on mdx files, the react and Vue jsx plugins will interfere with one another.

@Aaron-Pool
Copy link
Contributor

If either of you are still having problems, and can setup a minimal repo that I can debug with your configuration, I would be happy to!

@margielm
Copy link
Author

I did that in my original request.
Repo is here: https://github.com/margielm/sb-test. And the MDX file is here: https://github.com/margielm/sb-test/blob/master/stories/hello.stories.mdx .
If we want to spread the usage of Storybook for maximum extend, and we do because it is wonderful tool :), we need to make it a as simple as possible to setup for applications created with CLI. That applies not only to React or Vue, but also Angular, and others.

@Aaron-Pool
Copy link
Contributor

@margielm my apologies. I'm what some people would call "an idiot" 😬

I'll check it out ASAP.

@margielm
Copy link
Author

margielm commented Sep 17, 2019

No worries, it happens 😄 I am super glad that it is moving forward. Thank you!

@Aaron-Pool
Copy link
Contributor

Aaron-Pool commented Sep 18, 2019

So, it looks like this is indeed an issue with competing jsx loaders. The Vue jsx plugins are processing nthe MDX before the react plugin gets a chance to. And Vue jsx isn't valid in MDX content format yet. I'll try to chat with @shilman about the best way to get this fixed.

@shilman shilman changed the title Addon-docs: Simlest MDX is not working in vue app creared with @vue/cli Addon-docs: Simplest MDX is not working in vue app creared with @vue/cli Sep 19, 2019
@shilman shilman changed the title Addon-docs: Simplest MDX is not working in vue app creared with @vue/cli Addon-docs: Simplest MDX not working @vue/cli app Sep 19, 2019
@raihle
Copy link

raihle commented Sep 23, 2019

If you are not actually using JSX in Vue, the @vue/app preset makes it easy to disable as a workaround:

module.exports = {
  presets: [
    [
      '@vue/app',
      {
        /* Disabled due to clash between core-js versions in Storybook / Vue CLI */
        useBuiltIns: false,
        /* Disabled due to clash with Storybook MDX */
        jsx: false
      }
    ]
  ]
}

@shilman
Copy link
Member

shilman commented Sep 23, 2019

@raihle this is great intel, thanks for the tip!

@Aaron-Pool
Copy link
Contributor

@raihle thanks! That was an oversight on my part, and I definitely should have mentioned that. I use JSX pretty commonly, and I tend to forget that a large portion (probably even the majority) of the Vue user base doesn't need that part of the Babel preset at all.

@jeffwcx
Copy link

jeffwcx commented Oct 17, 2019

Unfortunately, I am the one use jsx in vue 😭

@Aaron-Pool
Copy link
Contributor

@jeffwcx I use JSX in my storybook project as well, and we're definitely set on getting it working. Stay tuned.

@LeBenLeBen
Copy link
Contributor

I had the same error, so I tried to disable JSX in the Vue babel preset, but then it's not able to parse the JSX in my Storybook config file to setup the inline rendering:

prepareForInline: storyFn => {
    const Story = toReact(storyFn());
    return <Story />;
},

It throws:

ERROR in ./config/storybook/config.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: ./config/storybook/config.js: Unexpected token (26:13)

  24 |     prepareForInline: storyFn => {
  25 |       const Story = toReact(storyFn());
> 26 |       return <Story />;
     |              ^

The Docs preset cause other issues with Prettier, that's why I went for the manual setup instead of the Docs preset. Any idea what's missing for Storybook to handle JSX in the config file? Or how I could rewrite the statement above without JSX at all?

@shilman
Copy link
Member

shilman commented Oct 19, 2019

@LeBenLeBen Try return React.createElement(Story)?

@LeBenLeBen
Copy link
Contributor

@shilman Perfect, it works fine, thank you!

@trevoreyre
Copy link
Contributor

As a temporary work-around, I was able to tweak the Storybook webpack config to get MDX stories working for Vue components without having to disable JSX. Many thanks to @Aaron-Pool for helping me debug. I set up an example repo here:

https://github.com/trevoreyre/storybook-mdx-vue-example

@andywd7
Copy link

andywd7 commented Jan 3, 2020

@trevoreyre This is a great temp work-around. It does seem however, for me at least, to break Jest unit tests as without a babel.config.js file with preset @vue/app in for Jest to pickup it errors when running the tests with Unexpected token {. Jest doesn't pick up the @vue/app preset specified in main.js.

Just wondering if anyone brighter than me, not hard, had any suggestions?

@robokozo
Copy link

robokozo commented Jan 3, 2020

As a point for consideration, I would greatly appreciate if the working setup/config could be packaged up as a vue cli plugin (with perhaps a pre-made .stories file to go along with the default HelloWorld.vue component)

@Aaron-Pool
Copy link
Contributor

@andywd7 I think you can configure environment specific settings in your Babel config. If you confine the changes in the work around to environments that aren't "test", I think that may work?

@pksunkara
Copy link
Member

pksunkara commented Jan 15, 2020

So, I worked on this yesterday and debugged the following.

In default Vue App serving storybook with the following in main.js

Default

  addons: [
    {
      name: '@storybook/addon-docs',
    }
  ]

results in the following error while viewing docs

ReferenceError: h is not defined

will give the following webpack config

/\.(stories|story).mdx$/
{
  "test": {},
  "use": [
    {
      "loader": "babel-loader",
      "options": {
        "cacheDirectory": "/Users/pksunkara/Coding/storybooks/docs/node_modules/.cache/storybook",
        "presets": [
          [
            "/Users/pksunkara/Coding/storybooks/docs/node_modules/@babel/preset-env/lib/index.js",
            {
              "shippedProposals": true,
              "useBuiltIns": "usage",
              "corejs": "3"
            }
          ]
        ],
        "plugins": [
          "/Users/pksunkara/Coding/storybooks/docs/node_modules/@babel/plugin-proposal-object-rest-spread/lib/index.js",
          "/Users/pksunkara/Coding/storybooks/docs/node_modules/@babel/plugin-proposal-class-properties/lib/index.js",
          "/Users/pksunkara/Coding/storybooks/docs/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js",
          [
            "/Users/pksunkara/Coding/storybooks/docs/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.js",
            {
              "sourceMap": true,
              "autoLabel": true
            }
          ],
          "/Users/pksunkara/Coding/storybooks/docs/node_modules/babel-plugin-macros/dist/index.js",
          "@babel/plugin-transform-react-jsx"
        ]
      }
    },
    {
      "loader": "@mdx-js/loader",
      "options": {
        "compilers": [
          null
        ]
      }
    }
  ]
}

With Options

  addons: [
    {
      name: '@storybook/addon-docs',
      options: {
        babelOptions: {
          presets: [
            [
              '@vue/cli-plugin-babel/preset',
              {
                jsx: false
              }
            ]
          ]
        }
      }
    }
  ]

works perfectly showing the docs with the following webpack config

/\.(stories|story).mdx$/
{
  "test": {},
  "use": [
    {
      "loader": "babel-loader",
      "options": {
        "presets": [
          [
            "@vue/cli-plugin-babel/preset",
            {
              "jsx": false
            }
          ]
        ],
        "plugins": [
          "@babel/plugin-transform-react-jsx"
        ]
      }
    },
    {
      "loader": "@mdx-js/loader",
      "options": {
        "compilers": [
          null
        ]
      }
    }
  ]
}

/cc @shilman @Aaron-Pool

So, the first question we can ask is, why is by default stories not taking babel config from babel.config.js. If it needs some stuff to work (babel-emotion), then why is it working correctly even though we removed them when passing babelOptions.

@AJB99
Copy link

AJB99 commented Feb 17, 2020

Has anyone found a reliable fix for this?

I've managed to get the Docs tab to render without error, but it doesn't actually render my component, just the text that would be the label for the button.

ui-button.vue

<template lang="pug">

	button
		slot

</template>



<script>

	let $cmp = {
		name : 'ui-button',
		props : {
			label : { type : String, default : 'UI Button' },
			options : {
				type : Object,
				required : false,
				default() {
					return {
						one : 1,
						two : 2,
						three : 'three'
					}
				}
			}
		}
	}

	export default $cmp

</script>



<style lang="stylus" scoped>

	button
		width 100%
		height 40px

</style>

babel.config.js

module.exports = {
  presets: [
    [
      '@vue/app',
      {
        /* Disabled due to clash between core-js versions in Storybook / Vue CLI */
        useBuiltIns: false,
        /* Disabled due to clash with Storybook MDX */
        jsx: false
      }
    ]
  ]
}

ui-button.stories.mdx

import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import uiButton from './ui-button.vue';

<Meta title="MDX/ui-button" component={ uiButton } />



# ui-button

With `MDX` we can define a story for `ui-button` right in the middle of our
markdown documentation.

<Story name="ui-button-story">
	{{
		template : '<ui-button>Click Me</ui-button>',
	}}
</Story>

Docs tab HTML
(Displays the text only, not a button).

<div id="root">
  <ui-button>Click Me</ui-button>
</div>

Any help would be much appreciated. We'd love to use Storybook for our project, but really do require mdx files to work properly.

@LeBenLeBen
Copy link
Contributor

I'm using the latest version of vue-cli-plugin-storybook in multiple projects and it works fine with docs.

@AJB99
Copy link

AJB99 commented Feb 17, 2020

@LeBenLeBen With docs, or with mdx files?

Also, could you please share your config so we can see if there's any diff between our configs and yours?

If you've got it working, then I'm sure a lot of people would love to take a look at how.

Also, can you provide the semver of what you mean by "latest version of the vue-cli-plugin-storybook" so we can all compare that as well.

@Aaron-Pool
Copy link
Contributor

@AJB99 is ui-button declared globally? If not, you need to add it to your story component definition, like:

<Story name="ui-button-story">
	{{
                components: { uiButton },
		template : '<ui-button>Click Me</ui-button>',
	}}
</Story>

The component attribute of the Meta tag is used by storybook to generate documentation automatically, whereas the contents of the Story block is just a Vue component definition that knows nothing about the rest of the file.

@LeBenLeBen
Copy link
Contributor

You can check out this repo that has a Vue CLI using the plugin for Storybook (under packages/chusho). It doesn't have any mdx file right now but I created one at some point and it worked fine.

In any case I think @Aaron-Pool is right and you should ensure your component is available for usage first.

@shilman
Copy link
Member

shilman commented Jun 16, 2020

Crikey!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-beta.29 containing PR #11185 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

@shilman
Copy link
Member

shilman commented Jul 10, 2020

Olé!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-rc.2 containing PR #11495 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

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

No branches or pull requests