Vue component docs with VuePress and @vuedoc/parser

Ismayil Khayredinov
4 min readApr 13, 2019

--

Update Jul 8, 2019: You can now see these in action and read the source code of the final solution.

This is not a plug-n-play tutorial, as it references my yet unreleased project. I am posting this as inspiration for people starting with Vue component documentation and looking for some tips and alternatives. I have tried a few tools out there, and in the end opted for doing things on my own.

I am a firm believer that inline documentation is the best way to provide helpful information about your code to anyone willing to look under the hood. It is also much easier to keep documentation up to date, when all of your docs are within reach — updating documentation with each code modification should be a habit if not a rule.

I have set out to write a UI framework for Vue, and getting things documented from early on is a personal mission. I have started my journey with Vue Design System, which is a great way to start your project, but I got quickly put away by having to use React on top of Vue, as well as the fact that I had little control over the layout and theming — I don’t believe in using JS objects to control the look and feel of my projects.

VuePress is a powerful static page generator, which affords a great level of control using Vue components, which is a natural choice for generating documentation for a Vue component library. I only had to solve 2 problems: first, I had to parse inline documentation from my Vue components and put them into VuePress, and second, I had to figure out how to create component demos and examples, without have to repeat myself too much.

Vuedoc Parser is an excellent library that extracts inline documetation tokens from Vue components. So, here is what I did to combine the two to provide a flexible system for component documentation.

Step 1: Install dependencies

Once you have setup your VuePress project, add the following dependencies to your project:

yarn install --dev @vuedoc/parser concurrently watch raw-loader vue-codemirror

concurrently is a great tool for parallelizing yarn/npm jobs. watch is a standard library for watching file system changes. raw-loader allows us to load Vue components as raw text to present the source code of our examples.vue-codemirror is a Vue component that encasulates thewidely used codemirror library for syntax highlighting.

Update your package.json scripts:

{
"scripts"
: {
"docs:dev": "yarn concurrently \"yarn components:parse\" \"yarn components:watch\" \"vuepress dev docs\"",
"docs:build": "yarn components:parse && vuepress build docs",
"components:parse": "babel-node ./docs/.scripts/parse.js",
"components:watch": "watch \"yarn components:parse\" ./src"
}
}

I am using ES6, hencebabel-node runs the component parsing script.

So, now when you run yarn docs:dev it will parse inline component documentation and then hot reload VuePress pages.

Update your .vuepress/enhanceApp.js to extend the Vue instance with VueCodeMirror :

import VueCodeMirror from 'vue-codemirror';

export default (
{
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData, // site metadata
},
) => {
Vue.use(VueCodeMirror);
}

2. Create a parser script

The contents on my ./docs/.scripts/parse.js looks like this:

Note that I use a config object to store all information about my components, which allows me to fine tune various aspects of each component. You can rewrite the script to instead iterate through your component directory tree. You can take a look at @vuedoc/md to see how they do it (I prefer to have a JSON object instead of md files, because then I can inject this data into a custom VuePress component and have control over the rendering of component docs).

Parsed inline docs indocs.json will look something like this:

3. Component Docs as a VuePress component

Now we want to render all these parsed tokens in a good-looking component (similar to the illustration at the start of the article). My example uses my own components, so you will need to rewrite this to use whatever component library you are using:

Now we can use this component anywhere in our VuePress markdown files.

---
title: Button
---

## Buttons

<ComponentMeta name="Button" />

4. Component Example as a VuePress component

VuePress is great for rendering code inline, but I wanted to be able to render more complex component examples and show their source code without having to duplicate the source code and the example Vue components.

To render the above example, I have created an entire example as a Vue single-file component and placed it under .vuepress/components/demos/Alert.vue . I have then created a custom component called ComponentDemo , which mounts the component and then loads its raw source and renders it using codemirror.

Now you can render a demo anywhere in your VuePress docs with: <ComponentDemo name="Alert"> , or whatever other demo you may have created.

---
title: Button
---

## Buttons

<ComponentMeta name="Button" />

### Default Buttons

<ComponentDemo name="DefaultButtons" />

Update Apr 18: I have run into issues with server-side rendering using codemirror. Solution is here: https://medium.com/@ismayilkhayredinov/codemirror-ssr-in-vuepress-529f4919ac97

--

--

Ismayil Khayredinov
Ismayil Khayredinov

Written by Ismayil Khayredinov

Software engineer who combines optimism with pessimism to build robust and idiot-proof solutions

Responses (1)