Mdx: Vue Support

Created on 24 Aug 2018  ·  14Comments  ·  Source: mdx-js/mdx

Hey guys, I'm in love with this library. Its super cool and easy to use. I use Vue in my day job, and I would really love to be able to write some component docs with this, because as far as I know - there is nothing in the Vue world for this, even though we have JSX.

I think its because of the differences that Vue needs, in comparison to being able to define a functional React component that makes it slightly non-trivial? I'm rusty with my parsers, so not sure how another layer of abstraction ontop of parsing with deciding to use a JSX outputter is.

i.e.

export default {
  render() {
    return <div>Hello World</div>;
  }
};

in comparison to:

const MyComponent = () => <div>Hello World</div>

I miss React. :) Would love to understand whether it was possible or not.

Thanks guys!

💎 v1 📚 aredocs 🦋 typenhancement

Most helpful comment

screen shot 2018-08-26 at 23 18 33

The markdown file:

import Test from './Test.vue';

# Hello World!

This is great!
_No React here!_

<Test />

Really enjoyed this! Surprised it works!!

I'm exhausted so won't get the PR just today - will do during the week, but basically the API I have proposed will look like this:

const { VueJSXCompiler } = require('@mdx-js/vue-plugin-mdx');
....
    module: {
      rules: [
        ...
        {
          test: /.mdx?$/,
          use: ['babel-loader', {
            loader: '@mdx-js/loader',
            options: {
              compilers: [VueJSXCompiler]
            }
          }],
        }
      ]
    }

So it means that a new package called @mdx-js/vue-plugin-mdx would be added. Theres also some knowledge of it in the loader in order to know whether to render Vue stuff or React stuff.

I'll need to look at the code with fresh eyes during the week before I open the PR. I'm sure I've duplicated one too many things.

All 14 comments

I have zero experience with Vue, but MDX has a compilers option which is an array of processors that operate on JSX. Maybe you could add a custom one there which modifies the final JSX output into something Vue-friendly?

What would really help is if you could take a look at JSX that MDX outputs and outline which changes in that JSX would be necessary for it to work in Vue.

I'm having a look into it @silvenon! As far as I understand theres a few tasks:

  1. Make compatible MDXTag and MDXProvider Vue components (I've worked on this today over at https://github.com/brennj/mdx/tree/vue-plugin ! I've written some tests to match the React side and looks good so far, maybe)
  2. Like you say, pass a custom compiler that will change the following code:
export default ({components, ...props}) => <MDXTag name="wrapper"  components={components}><MDXTag name="p" components={components}>{`Hello World!`}</MDXTag></MDXTag>

into Vue friendly code. I'm still trying to figure this bit out as theres some specific React parts in the loader and stuff but I think it should be fairly fine. I might see how far I can get and offer up a PR if I'm happy with it :)

screen shot 2018-08-26 at 23 18 33

The markdown file:

import Test from './Test.vue';

# Hello World!

This is great!
_No React here!_

<Test />

Really enjoyed this! Surprised it works!!

I'm exhausted so won't get the PR just today - will do during the week, but basically the API I have proposed will look like this:

const { VueJSXCompiler } = require('@mdx-js/vue-plugin-mdx');
....
    module: {
      rules: [
        ...
        {
          test: /.mdx?$/,
          use: ['babel-loader', {
            loader: '@mdx-js/loader',
            options: {
              compilers: [VueJSXCompiler]
            }
          }],
        }
      ]
    }

So it means that a new package called @mdx-js/vue-plugin-mdx would be added. Theres also some knowledge of it in the loader in order to know whether to render Vue stuff or React stuff.

I'll need to look at the code with fresh eyes during the week before I open the PR. I'm sure I've duplicated one too many things.

I have a PR open (https://github.com/mdx-js/mdx/pull/455) that gets us a lot of the way there thanks to the fine work of @brennj.

I'm currently stuck on the way Vue handles element creation (I've never really used it before 🙃). I've created the custom pragma function for Vue to receive the type and props which is happening as expected. But, for whatever reason I can't seem to get it to render.

If anyone wants to tinker around in that branch there's a directory (examples/vue) you can get running and then edit packages/vue/create-element.js. Would love any insights as to what I'm doing wrong.

A working createElement (and related code) is merged into #455

A vanilla install from the MDX Vue example fails with:

image

A new Vue beta is now shipped in the latest version of MDX thanks to @codebender828! 🎉

Hi everybody, Would anyone have a pointer at a working example on how to embed a Vue component into a Markdown file? As far as I understand, @mdx-js/vue allows to expose a Markdown file as a Vue component, but how to achieve the other way round (it seems the vue-plugin-mdx by @brennj does not exist as such anymore), that is for instance, as mentioned above:

import Test from './Test.vue';

# Hello World!

<Test />

Hey @calaoa ! Yes it's possible to consume Vue components in your MDX files. You'd need to consume it as JSX in your MDX file.

Here's an example of how consume Vue components in MDX files.

(This is an old demo but works. I made this when I was working on adding support for Vue.js. All functionality is already added to the MDX package.)
Demo: https://mdx-vue.now.sh/

Thanks a lot @codebender828! Meantime I just noticed that @mdx-js/examples/vue is showcasing an example along this line as well. Quite powerful... Now wondering how to load mdx files dynamically into a Vue app without the need to hardcode any mdx file import into the source code, a bit like what @nuxt/content offers (see the first demo video illustrating a Markdown file calling a Vue component as far as I understand)...

@calaoa I'm excited about @nuxt/content — what was your experience like? Interested to know your thoughts comparing it to MDX + Vue.

Hey @callumflack, @nuxt/content looks very appealing indeed, however there's two things I'm not fond of so far with it (a plugin could come into play for the first one I guess, I need to experiment further):

  • Search: I favor MiniSearch over Loki
  • TypeScript: as far as I can see, @nuxt/content is not using TypeScript (yet)

(Hopefully not hijacking the thread too much… MDX + Vue opens so many paths… E.g. something like Jupyter with an MDX-Vue-Node-Git stack… A route I'm humbly exploring with Babouk…)

For what it's worth, I actually achieved the usage of Vue components 'within' (sort of) Markdown by using v-runtime-template👏 coupled with remark-rehype (and other remark's👏): Markdown gets transformed to HTML, then the embedded Vue tags are made executable by v-runtime-template (provided the Vue displaying the result imports the components declared in the Markdown, which can be made dynamic as well via Vue async components👏). Eventually nothing involving MDX here yet (possible follow up though), sorry for the noise.

Thanks @calaoa — I see your digital garden fascination! I've got similar interests. Markdown + components can mean rich, interactive "gardening" w/o being tied to a platform. I hope people like you can make new information systems with these tools. As such, it's a good thing to converse about them here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

johno picture johno  ·  4Comments

dioptre picture dioptre  ·  3Comments

Exelord picture Exelord  ·  4Comments

EddyVinck picture EddyVinck  ·  3Comments

codebender828 picture codebender828  ·  4Comments