[go: nahoru, domu]

Skip to content

Instantly share code, notes, and snippets.

@shilman
Last active January 23, 2024 03:43
Show Gist options
  • Save shilman/036313ffa3af52ca986b375d90ea46b0 to your computer and use it in GitHub Desktop.
Save shilman/036313ffa3af52ca986b375d90ea46b0 to your computer and use it in GitHub Desktop.
Storybook React props handling for Typescript

NOTE: This was written in 2020 and has been superseded by docs at storybook.js.org

Storybook React props handling for Typescript

We've flip-flopped on prop table handling for React components written in Typescript. This document attempts to be a final reference for anybody who's been trying to follow along.

TLDR:

SB6 uses react-docgen-typescript by default. We hope to use react-docgen in SB7. The whole experience led to zero-config in SB6, so it's now a one-line change main.js to switch between the two.

TOC:

What's docgen and why should I care?

Docgen is a processor that analyzes the source code of your components to generate props tables in Storybook Docs.

Example prop table, with extracted type information displayed in the Description column, and (potentially) inferred UI control in the Control column:

react-docgen-typescript vs. react-docgen

For React Typescript, there are two primary choices: react-docgen-typescript and react-docgen. Each has its distinctive strengths and weaknesses (as of this writing).

react-docgen-typescript react-docgen
Features Great. The analysis produces great results which gives the best props table experience. OK. React-docgen produces basic results that are fine for most use cases.
Performance Slow. It's doing a lot more work to produce those results, and may also have an inefficient implementation. Blazing fast. Adding it to your project increases build time negligibly.
Bugs Many. There are a lot of corner cases that are not handled properly, and are annoying for developers. Few. But there's a dealbreaker, that ultimately led us to not choose this as the default.
Community Small. It's a relatively niche project. Large. Widely used and more contributors.
SB docs Good. Our prop tables have supported react-docgen-typescript results from the beginning, so it's relatively stable. OK. There are some obvious improvements to fully support react-docgen, and they're coming soon.

Performance is a common question, so here are build times from a random project to quantify. Your mileage may vary:

Docgen Build time
react-docgen-typescript 59s
react-docgen 29s
none 28s

Why did you flip-flop?

Originally, react-docgen-typescript was the only game in town, and Storybook has recommended it for Typescript handling for years. In late 2019, react-docgen got Typescript support. After an initial evaluation (see above), we chose to react-docgen as the default. Here's what I wrote at the time:

  1. there are LOTS of bugs in react-docgen-typescript-loader that are already fixed in react-docgen
  2. going "all in" on one library simplifies support and maintenance on the storybook side
  3. react-docgen seems to have critical mass, react-styleguidist also adopted it in v11.0
  4. you can still use the old configuration if needed (for now)

In mid-6.0, we made the switch, which involved a bunch of surgery in Storybook. Unfortunately, we ran into a key bug in react-docgen, which is lack of support for imported types.

react-docgen missing imported type support

What that means is that when a component uses a type defined in another file or package, react-docgen is unable to extract props information for that type.

So in the following example, SomeType would simply be ignored!

import React, { FC } from 'react';
import SomeType from './someFile';

type NewType = SomeType & { foo: string };
const MyComponent: FC<NewType> = ...

We didn't grasp the significance of this limitation when we switched, and encouraged our users to upvote the PR in react-docgen which purports to fix this issue. Despite 100 upvotes, the PR has been open for a year. (If you're reading this, please upvote!!!)

As users started to switch to the SB6 react-docgen default, feedback started to build that this is a dealbreaker for most projects.

So, reluctantly after lots of wrangling, we switched the default back to react-docgen-typescript as the default in 6.0.

However, we "failed forward" in the sense that we used the situation as an excuse to build in zero-config typescript support in 6.0, and made it possible for users to switch between the two configurations with a one-line change.

What should I do as a user?

Short-term

Short-term, we believe that react-docgen-typescript is the best choice for Props extraction in Storybook.

If you're not using Props tables, need the speed, or can live without imported type support, you can add the following lines to your .storybook/main.js:

module.exports = {
  typescript: {
    reactDocgen: 'react-docgen`
  }
}

Medium-term

As soon as react-docgen supports imported types, we believe that it will be the obvious choice for all the reasons listed above, and we will recommend users switch using the above method.

In SB7, we hope to make react-docgen the default by the same rationale as above. We will continue to support react-docgen-typescript for the foreseeable future.

Long-term

Long-term, we hope the community can converge on a single standard, and the Storybook can help with that convergence.

@ScottAwesome
Copy link
ScottAwesome commented Jun 17, 2022

@shilman Has the merger of #424 changed this at all?

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