Page MenuHomePhabricator

Evaluate and choose a demo tool (Storybook, VitePress, …)
Closed, ResolvedPublic

Description

UI component library demo tool

Background

Storybook has been the tool of choice both for demoing a library/design system and for use during the development process by WMF and WMDE teams. Storybook is a powerful tool with many useful features and addons that can empower developers to create documentation and interactive demos.

Evaluation

However, Storybook has its downsides. Here are a few I've run into:

  • Configuration and story-writing aren't straightforward, especially when you're first learning. While text documentation only requires markdown knowledge, you must be comfortable with JavaScript to edit stories (e.g. component documentation)
  • Storybook isn't built for Vue and this shows both when writing stories and reading the docs.
  • Stories are not the same as normal Vue components, which means the demos we're creating don't line up 1:1 with the code an end user needs to use that component. For this reason and others, the code samples displayed on the demo tab are not sufficient for our needs (see T287049).
  • It has many dependencies (e.g. the docs addon requires markdown, which requires react)
  • I set up Storybook with Vite/Vue 3 in an experimental project, using storybook-builder-vite, an experimental library in its early stages, and ran into issues:
    • Source code isn't working, both in the story source panel in the addons tab, or in the "show code" feature on the docs tab. This is a critical feature for us (see this PR for details)
    • HMR doesn't work when you're editing a story file
  • Storybook conflicts with some of the tools we want to use to facilitate TypeScript development (Volar and vue-tsc)
Must-haves
  • Presentation of all components & patterns, interactive and the underlying code
    • Presentation of props/slots/actions/events per component/pattern
    • Presentation of all component/pattern types, even obscure ones
    • Demos include code samples that can be directly referenced for usage (e.g. a user should be able to copy/paste a code sample to use as a starting point)
  • Presentation of icon tokens, including all language variants
  • Interactive (HMR – hot module replacement) presentation of components/patterns
Nice-to-haves
  • Presentation of all component states
  • Presentation of involved tokens building the component/pattern
  • Open source tool with big developer community to build on progress and maintenance from the outside
  • Similar underlying technology (not far off Vue.js)
  • Plugin ecosystem to build on top
    • (Technical) Accessibility plugin
    • Responsive viewport plugin
    • Visual impairment filter plugin
    • Measurement plugin
    • Themability plugin (dark/black/white…)
  • Adding components/patterns to demo is simple without a lot of technical finesse
  • JavaScript knowledge is not needed to edit documentation
  • Editing documentation requires only knowledge of Markdown
  • Low dependencies
  • Long-term maintenance simple and reliable.
  • On brand with Design Style Guide
  • Visual regression tooling
Alternatives: VitePress

Now that we have decided to use Vite to build the new library, we may want to consider VitePress, a Vue-powered static site generator built with Vite (as opposed to VuePress, which is built with Webpack), or other options.


Exploration

I've been building a proof-of-concept static site with VitePress in this repository.

You can visit the static site here.

Event Timeline

I've been playing around with VitePress in the repo we've been using to experiment with Vue 3, Vite, and other stuff (see the docs directory here). Though the final product generated by VitePress is quite different from Storybook, I think using VitePress may be more ideal for our needs.

Check out the static site here.

To try it out locally, clone this repo, then run:

nvm use 12.21.0
npm install
npm run docs:dev

Note that all the documentation I've included is for demo purposes only.

About VitePress

  • VitePress is small with fewer dependencies than Storybook
  • VitePress is fast: starting up takes a second or two, and HMR works
  • Pages on the generated site are built in Markdown. See the docs for everything you can do in Markdown
  • VitePress is very new and experimental, so bugs might crop up (although I didn't experience any yet). That said, the Storybook builder for Vite is also new and experimental and I've already encountered bugs.
  • VitePress is intended to be very light, so it will never be as fully-featured as Storybook

About the static site

  • The generated site is approachable and well-organized. There's a lot we can customize, but it's also in a standard, minimal, clean format that many of us are used to. You're losing all of the interactivity and controls of Storybook, but gaining docs that are much easier to read and quickly understand, especially for non-developers
  • The generated site is very similar in structure to the Design Style Guide. I personally think we should combine the Design Style Guide and the new component library in order to have a single source of truth for our design system, or at least house them together, something I can't imagine doing in Storybook. For one, we'd be stuck with the visual style of Storybook for design documentation. Plus, if we want non-developers to be able to update the docs (which I absolutely do), using markdown in VitePress seems ideal.
Component documentation
  • You can use Vue within markdown. See the Button and Radio components: the Button component is simple enough that we can just use it directly in the markdown file, while the Radio is better demonstrated by showing the entire parent component. We can do both of these things easily in the markdown file. See template.md for instructions on setting up a component file similar to the existing ones. Either way, the component demos are just normal Vue components, which is both more realistic and more straightforward than the Storybook versions.
  • One problem we'd need to solve is how to include documentation that used to live in comments in the component file. Storybook automatically generates a props/slots/events table, and pulls comments from the component docblock. We get none of that with VitePress and would either need to duplicate the documentation or only house it in the demo, assuming that anyone who's editing the component file can look at the docs site. I would recommend the latter. I also had to manually create tables for props, slots, and events, although these wouldn't have to be done from scratch every time with the use of the template.
  • We can set up custom components to be used in the docs. I set up a Wrapper component that is available globally in the docs so you can use it in any file without needing to import it. It offers some formatting and a show code/hide code button, similar to what we get with Storybook. A custom component could also be used to pull in and display component props/events/slots as mentioned above.

TL;DR: I think VitePress would allow us to open up editing documentation to more people, would keep our toolset lighter, and would make component documentation simpler. I think the amount of manual work currently needed to create component documentation is balanced by the fact that everything is more straightforward (you're just creating normal Vue components and writing markdown) and easy to configure. Plus, we can build some tools to facilitate this process and make it more automated.

I also have some concerns about storybook. It is indeed a widely used project and actively developed one. Setting it up for Vue and start using it is also very easy. But once all those initial setup is done, I observed that its huge dependency system becomes a headache. It brings a huge list of react library dependencies and takes too much disc space. npm audit giving security warnings about these depdendencies becomes very common. (This recent HN thread has similar observations). But replacing it with something else is not going to be easy.

I have used vitepress for project documentation and its support for embedding Vue components is amazing. So your experiment with it is good direction. But manually preparing the documentation for each component is not appealing to me though. Viewports, Knobs, Actions, Accessibility plugins are so useful. Since we need this as a demo site, allowing users to try out props with in the system is really useful. Documentation and demo referring the actual code helps developers also to use that system to validate their work.

I did some reading on how storybook generate the documentation about props and slots by parsing Vue SFCs. It uses vue-docgen-api for this. But its Vue 3 support is not ready. Vuetify uses its api-generator system which also does component file parsing.

I am not sure whether we should venture into building by our on or working with any existing project to build this automatic doc generation.

@santhosh thanks for sharing that info about how Storybook generates the Vue docs. I think it would be worth us trying to implement something similar, hopefully using one of these existing solutions, especially since we could share it with others in the Vue community trying to move away from Storybook. I'm particularly concerned about the risk of outdated docs that comes with a manual documentation process, e.g. if we update a component but forget to update the relevant docs.

I'm of two minds when it comes to interactive component demos. Of course, it's a useful feature of Storybook for both designers and developers to quickly play around with available props and slots, and for trying to break things during QA. However, it means that component demos aren't demonstrative of real-world applications of those components. This is somewhat extreme in Storybook, but even if we rolled our own system, we'd be building components for the specific use case of interactive demos, and not demonstrating the code an end user would actually want to use as a starting point. To make up for the lack of interactivity, we'd want to build demos that showcased all the available states/variations of a component, which is indeed a manual process (unless we come up with some helpers or automation). It's a trade-off we'll have to evaluate.

I was able to use vue-docgen-cli to set up automatically generated component documentation in my VitePress example. See code involved here. With some configuration and a custom template for component pages, running npm run styleguide will now generate component pages that includes:

  • Description paragraph generated from the component docblock comment
  • Custom component demos, build in markdown files in the component source directories (e.g. src/components/radio/Radio.md)
  • Auto-generated props, events, and slots tables

There's more we can do in both the component page template and in documentation comments in the component Vue files, and this might not work perfectly with all Vue 3 code yet, but this at least solves the problems of having to manually create these tables and duplicating documentation.

There's a lot of potential in the shown VitePress setup and it tackles several nasty issues with current separation of Design Style Guide (DSG) and component presentation. At best we will find a low-maintenance, low effort demoing solution that enables us to provide high value to consumers including the pieces that Santhosh has been talking about like Storybook plugins for responsive mode or accessibility. Still a good outcome, we're able to take learnings from the exploration to refine the DSG and the connected demoing solution.
In this regard, I'm wondering how simple we might setup VitePress might be to setup with our own i18n libraries. Missing internationalization was one of the main drivers behind past considerations of using a static site generator over static HTML files for the Design Style Guide, see T164449

One thing to keep in mind when selecting a demo tool (a "must-have" for WMDE) is whether it enables us to integrate visual regression testing in our pipeline.

Storybook facilitates this via Chromatic. This testing tool conducts 3 PR checks: Publish (publishes the PR changes to a Storybook workspace, so we can fully check any new/modified components before they're merged), UI Review and UI Test. So it allows us to detect visual alterations, and to gather UI feedback: in fact, designers are in charge of reviewing and approving any visual or behavioral changes using Chromatic, as part of our PR checks. This is a workflow that has proven to be really useful, and we would recommend incorporating a similar process in the new library.

Find more information available in the "Services" section of WiKit's "Contributing" documentation page.

Volker_E renamed this task from Evaluate and choose a demo tool to Evaluate and choose a demo tool (Storybook, VitePress, …).Sep 21 2021, 8:42 PM

Two points I've brought up in yesterday's front-end standards group meeting:

  • An angle we should be taking into account is to find a solution that is possibly becoming the standard demo tool for front-end demoing in the Foundation. Readers Web, Language team, Wikimedia Deutschland all have been gathering experience in Storybook as a quasi-standard tool nowadays, its use is problematic for the given reasons, and specifically with it being built with React. These teams have been using it for non-Vue based front-end, which will also continue to be a reality in our environment.
  • The interweaving of component library and the general Design Style Guide. It would be a wishful outcome of a future solution to have these two documentations closer together, maybe continue to have them in separate repos, but on brand and stronger interlinked (interactive component demos in “Components” section for example) to present a clearer vision to general audience. An important improvement and resolution to a long-term quest would be internationalization support for the DSG, maybe we could consider VuePress for the DSG T164449…?

The issues described for Storybook seem quite relevant.
When looking at the alternatives such as VitePress my concern is that it seems a more generic tool, not specific for UI documentation/inspection/review/testing. Covering that gap of features, maintenance and documentation seems a project on its own.

Thanks to everyone who has provided feedback on this decision! We have decided to move forward with VitePress on an experimental basis. This means we will set it up in the new library and continue to add and investigate new functionality. As we build out the new library, we'll continually evaluate whether we can reasonably achieve our goals with VitePress. Worst case scenario, if we decide VitePress won't cut it, we can switch back to Storybook.

We plan to investigate the following:

  • Adding controls for interactively configuring demo component props and slots (in progress, see demo and code)
  • How to isolate component demos from VitePress styles
  • Adding a theme selector that implements basic styles from common MediaWiki skins to better demonstrate what the component will look like in in that environment
  • How we could implement internationalization
  • Adding search, and whether the option for configuring search in VitePress will be sufficient
  • How we could consolidate working components demos with the Design Style Guide to avoid redundancy and host our resources in a single place (even if that means a separate section of the VitePress site for design docs)
  • How we might form a working relationship with VitePress maintainers/community
  • Deploying a staging version of the static site per patch/PR for design review
  • Whether the next version of VuePress, which supports Vue 3 and Vite, might be better for our needs

And we'll continue to evaluate non-VitePress options for automated accessibility (T291945) and visual regression testing (T291525).

We also want to keep in mind that we have limited resources to develop and maintain the new library, so we will continue to evaluate if we feel the development and maintenance costs of VitePress are reasonable.

I'm closing this ticket now, but please feel free to continue adding comments if there are more considerations.

AnneT claimed this task.