Open rikkit opened 2 years ago
Can you test the minor releases from 6.0 to 6.4 to help us identify where the regression happened?
This most likely broke in 6.4
@tmeasday any suggestions?
@shilman I'm not aware of anything that's changed WRT to docgen? Did we bump versions? The only code I personally have looked at that deals with docgen was using the output of it; I didn't actually change the __docgenInfo
annotations themselves.
i'm facing a somewhat similar issue in that @see
tags do not show up on my docs pages. i was hoping to access jsdoc tags to finally implement extractComponentDescription
myself (i've had this issue for a while now 😅).
after doing some digging, i think part of the issue here is that __docgenInfo
is not the entire ComponentDoc
object. it only includes description
, displayName
, and props
:
not sure just how new of a feature this is, but react-docgen-typescript
actually includes jsdoc tags as a separate property:
[
{
tags: {
see: 'https://developer.mozilla.org/docs/Web/HTML/Element/a\n' +
'https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement\n' +
'https://www.w3.org/TR/wai-aria-practices-1.1/#link'
},
description: 'Renders an HTML `<a>` element.\n' +
'\n' +
'`Anchor` is a widget that provides an interactive reference to a resource.\n' +
'The target resource, `href`, can be either external or local (either outside\n' +
'or within the current page or application).',
displayName: 'Anchor',
methods: [],
props: {
slot: [Object],
style: [Object],
title: [Object],
type: [Object],
name: [Object],
ref: [Object],
key: [Object],
download: [Object],
href: [Object],
hrefLang: [Object],
media: [Object],
ping: [Object],
rel: [Object],
target: [Object],
referrerPolicy: [Object],
defaultChecked: [Object],
defaultValue: [Object],
suppressContentEditableWarning: [Object],
suppressHydrationWarning: [Object],
accessKey: [Object],
className: [Object],
contentEditable: [Object],
contextMenu: [Object],
dir: [Object],
draggable: [Object],
hidden: [Object],
id: [Object],
lang: [Object],
placeholder: [Object],
spellCheck: [Object],
tabIndex: [Object],
translate: [Object],
radioGroup: [Object],
role: [Object],
about: [Object],
datatype: [Object],
inlist: [Object],
prefix: [Object],
property: [Object],
resource: [Object],
typeof: [Object],
vocab: [Object],
autoCapitalize: [Object],
autoCorrect: [Object],
autoSave: [Object],
color: [Object],
results: [Object],
security: [Object],
unselectable: [Object],
inputMode: [Object],
is: [Object],
children: [Object],
dangerouslySetInnerHTML: [Object],
disabled: [Object],
theme: [Object],
as: [Object],
forwardedAs: [Object]
},
expression: SymbolObject {
flags: 524288,
escapedName: 'StyledComponent',
declarations: [Array],
parent: [SymbolObject],
isReferenced: 788968,
id: 446
}
}
]
@storybook/react
: 6.5.0-beta.8
@storybook/react-docgen-typescript-plugin
: 1.0.1
react-docgen-typescript
: 2.2.2
The change to move JSDoc tags into the tags
property must be the issue - that didn't used to be the case, the tags were just in the string.
Where does __docgenInfo
get created? When I looked I wasn't able to track down where this actually came from...
@rikkit howdy! i finally had a chance to dig in and do some more debugging, so i'm back with a few updates! hopefully they'll still be of some help to you.
first, react-docgen-typescript
supports an option titled shouldIncludePropTagMap
. not sure when it was introduced, but when set to true
, ComponentDoc
objects include a tags
property (i think i had this set when i originally posted, otherwise i don't think i would've noticed the change in the first place). to pass the option via storybook, set shouldIncludePropTagMap
under typescript.reactDocgenTypescriptOptions
.
to answer your question - for both @storybook/react-docgen-typescript-plugin
and @joshwooding/vite-plugin-react-docgen-typescript
, i'm 98.999% sure __docgenInfo
is created via setComponentDocGen
. it's somewhat hidden given the implementations, but if you search "__docgenInfo" while on either page, you should be able to track it down. if that doesn't tickle your fancy, here's a simplified version of the same core logic (excuse the shameless code plug 😅):
import MagicString from 'magic-string'
import micromatch from 'micromatch'
import path from 'node:path'
import {
withCustomConfig,
type ComponentDoc,
type FileParser
} from 'react-docgen-typescript'
import type { TransformResult } from 'rollup'
import dedent from 'ts-dedent'
import type { Plugin } from 'vite'
import { PLUGIN_NAME } from './constants'
import type Options from './options.interface'
/**
* Creates a `react-docgen-typescript` plugin.
*
* @see https://github.com/styleguidist/react-docgen-typescript
* @see https://vitejs.dev/guide/api-plugin.html
*
* @param {Options} [options] - Plugin options
* @return {Plugin} Vite `react-docgen-typescript` plugin
*/
const docgen = ({
apply,
componentNameResolver,
enforce = 'pre',
customComponentTypes = [],
exclude = ['**.stories.tsx'],
handler = doc => doc,
include = ['**.tsx'],
name = doc => doc.displayName,
propFilter = prop => !prop.parent?.fileName.includes('node_modules'),
savePropValueAsString = false,
shouldExtractLiteralValuesFromEnum = false,
shouldExtractValuesFromUnion = false,
shouldIncludeExpression = false,
shouldIncludePropTagMap = true,
shouldRemoveUndefinedFromOptional = true,
skipChildrenPropWithoutDoc = true,
tsconfigPath = path.resolve('tsconfig.json')
}: Options = {}): Plugin => {
/**
* Component docgen info parser.
*
* @see https://github.com/styleguidist/react-docgen-typescript#usage
*
* @const {FileParser} parser
*/
const parser: FileParser = withCustomConfig(tsconfigPath, {
componentNameResolver,
customComponentTypes,
propFilter,
savePropValueAsString,
shouldExtractLiteralValuesFromEnum,
shouldExtractValuesFromUnion,
shouldIncludeExpression,
shouldIncludePropTagMap,
shouldRemoveUndefinedFromOptional,
skipChildrenPropWithoutDoc
})
return {
apply,
enforce,
name: PLUGIN_NAME,
/**
* Parses component docgen info from `id`.
*
* The final transform result will include a new source map and updated
* version of `code` that includes a code block to attach a `__docgenInfo`
* property to the component exported from `id`.
*
* If `id` isn't explicity included via {@link include}, or is explicity
* excluded from transformation via {@link exclude}, `undefined` will be
* returned instead.
*
* @param {string} code - Source code
* @param {string} id - Module id
* @return {Exclude<TransformResult, string>} Transformation result
*/
transform(code: string, id: string): Exclude<TransformResult, string> {
// do nothing if file isn't explicity omitted
if (!micromatch.isMatch(id, include)) return
// do nothing if file is explicity omitted
if (micromatch.isMatch(id, exclude)) return
try {
/**
* Component docgen info.
*
* @see https://github.com/styleguidist/react-docgen-typescript/blob/v2.2.2/src/parser.ts#L16
*
* @var {ComponentDoc?} doc
*/
let doc: ComponentDoc | undefined = parser.parse(id).pop()
// bail if missing component docgen info
if (!doc) return null
/**
* {@link code} as `MagicString`.
*
* @see https://github.com/Rich-Harris/magic-string
*
* @const {MagicString} src
*/
const src: MagicString = new MagicString(code)
// apply additional transformations to component docgen info
doc = handler(doc, id, code)
/**
* Code block containing logic to attach a `__docgenInfo` property to
* the component in found in {@link code}.
*
* @const {string} docgenblock
*/
const docgenblock: string = dedent`
try {
${name(doc, id, code)}.__docgenInfo=${JSON.stringify(doc)};
} catch (e) {
console.error('[${PLUGIN_NAME}]' + ' ' + e.message, e)
}
`
// add __docgenInfo code block to source code
src.append(docgenblock)
return {
code: src.toString(),
map: src.generateMap({ hires: true, source: id })
}
} catch (e: unknown) {
return void console.error(e instanceof Error ? e.message : e)
}
}
}
}
export default docgen
side note: i'm using storybook with vite now, so that's why i included the info about the vite plugin. i'm using a custom vite plugin rather than @joshwooding/vite-plugin-react-docgen-typescript
because i was debugging an issue with my docs not reflecting changes during development.
Is there any news on this ? The typescript.reactDocgenTypescriptOptions.shouldIncludePropTagMap : true
fix doesn't seem to be working on my side...
Is your feature request related to a problem? Please describe
tl;dr; I was using SB 6.0 and recently upgraded to SB 6.4. I used to have something working, and now __docgenInfo doesn't contain the data I need. Looking for a pointer to how to get it back!
I'm maintaining a design system. We're using Storybook for documentation reasons. One of the ideas we had was to extend the feature of addon docs that shows JSDoc comments on docs pages. If there is e.g. an
@status deprecated
tag on the component we'd show a red deprecated label on the component's doc page. There was also@status stable
,@status development
,@status review
.This feature was working in SB6.0 with the following decorator. Essentially, look at
__docgenInfo.description
, do a regex match, and set__docgenInfo.status
if one is present.An example of a story:
I upgraded to SB6.4 and now it appears that
__docgenInfo.description
now never contains any@
JSDoc tags.I have looked through the sources of
addon-docs
,react-docgen
,babel-plugin-react-docgen
but I can't track down where the comment is actually parsed from the story source...Describe the solution you'd like
A pointer to where/ when this was changed, or a way to access the raw JSDoc comment again.
Describe alternatives you've considered To not do this ;)
Are you able to assist to bring the feature to reality? Sure if I know where to look....
Additional context Thanks!