Skip to content

Commit 9e440ad

Browse files
authored
Update docs (#1091)
* Add security warnings for cli options * Fix docs * More docs * Fix cli
1 parent a955aa8 commit 9e440ad

31 files changed

Lines changed: 1213 additions & 63 deletions

File tree

packages/react-docgen-cli/src/commands/parse/command.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,18 @@ program
7979
'--resolver <resolvers>',
8080
`Built-in resolver config (${Object.values(ResolverConfigs).join(
8181
', ',
82-
)}), package name or path to a module that exports a resolver. Can also be used multiple times. When used, no default handlers will be added.`,
82+
)}), package name or path to a trusted module that exports a resolver. Can also be used multiple times. When used, no default resolvers will be added.`,
8383
collect,
8484
defaultResolvers,
8585
)
8686
.option(
8787
'--importer <importer>',
88-
'Built-in importer name (fsImport, ignoreImporter), package name or path to a module that exports an importer.',
88+
'Built-in importer name (fsImporter, ignoreImporter), package name or path to a trusted module that exports an importer.',
8989
'fsImporter',
9090
)
9191
.option(
9292
'--handler <handlers>',
93-
'Comma separated list of handlers to use. Can also be used multiple times. When used, no default handlers will be added.',
93+
'Comma separated list of trusted handlers to use. Can also be used multiple times. When used, no default handlers will be added.',
9494
collect,
9595
defaultHandlers,
9696
)
@@ -109,7 +109,7 @@ program
109109

110110
let finalIgnores = ignore;
111111

112-
// Push the default ignores unless the --no-default-ignore is set
112+
// Push the default ignores unless the --no-default-ignores is set
113113
if (defaultIgnores === true && ignore !== defaultIgnoreGlobs) {
114114
finalIgnores.push(...defaultIgnoreGlobs);
115115
} else if (defaultIgnores === false && ignore === defaultIgnoreGlobs) {
Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,54 @@
1-
import ContentMissing from '@/components/ContentMissing';
2-
31
# Architecture
42

5-
<ContentMissing />
3+
react-docgen works in four steps:
4+
5+
1. Parse the source code with Babel.
6+
2. Build a [`FileState`](../reference/file-state) object around the AST.
7+
3. Run a resolver to find React component definitions.
8+
4. Run handlers on each component definition and build the final documentation.
9+
10+
## Parsing
11+
12+
`parse()` accepts source code and a config object. The source is parsed with
13+
Babel. If no Babel config file is found, react-docgen applies default parser
14+
plugins for JSX and either TypeScript or Flow.
15+
16+
TypeScript syntax is enabled by default for filenames ending in `.ts`, `.tsx`,
17+
`.mts`, or `.cts`. Other files use Flow syntax by default.
18+
19+
## FileState
20+
21+
`FileState` stores the AST, root program path, source code, parser options, and
22+
the configured importer. It also provides helpers used by resolvers, handlers,
23+
and utilities:
24+
25+
- `file.traverse()` to walk the AST
26+
- `file.import()` to resolve imported values
27+
- `file.parse()` to parse another file with the same importer
28+
29+
## Resolvers
30+
31+
The resolver receives the `FileState` and returns component definition paths.
32+
33+
The default parser config uses a chain of built-in resolvers to find exported
34+
components and annotated components. Custom resolvers can replace that behavior.
35+
36+
## Handlers
37+
38+
Handlers receive a `DocumentationBuilder` and one component definition. Each
39+
handler adds one kind of information, such as prop types, default props, display
40+
name, or component methods.
41+
42+
When all handlers have run, the builder produces a `Documentation` object.
43+
44+
## Importers
45+
46+
Importers are used when react-docgen needs to follow imports. The default
47+
filesystem importer resolves imported source files from disk. The ignore
48+
importer disables cross-file resolution.
49+
50+
## Output
51+
52+
The JavaScript API returns an array of `Documentation` objects. The CLI returns
53+
a JSON object keyed by file path, where each value is an array of
54+
`Documentation` objects for that file.
Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,69 @@
1-
import ContentMissing from '@/components/ContentMissing';
2-
31
# Handler
42

5-
<ContentMissing />
3+
Handlers extract information from every component found by the resolver. A
4+
handler receives a `DocumentationBuilder` and the Babel `NodePath` for the
5+
component definition.
6+
7+
```ts
8+
import type { Handler } from 'react-docgen';
9+
10+
const handler: Handler = (documentation, componentDefinition) => {
11+
documentation.set('customValue', componentDefinition.node.type);
12+
};
13+
```
14+
15+
## Signature
16+
17+
```ts
18+
type Handler = (
19+
documentation: DocumentationBuilder,
20+
componentDefinition: NodePath<ComponentNode>,
21+
) => void;
22+
```
23+
24+
## Writing data
25+
26+
Use the methods on `DocumentationBuilder` to add data.
27+
28+
```ts
29+
documentation.set('displayName', 'Button');
30+
documentation.addComposes('./otherProps');
31+
32+
const prop = documentation.getPropDescriptor('label');
33+
prop.description = 'Text shown inside the button.';
34+
```
35+
36+
For context-related handlers, use:
37+
38+
```ts
39+
documentation.getContextDescriptor('theme');
40+
documentation.getChildContextDescriptor('theme');
41+
```
42+
43+
## Using a custom handler
44+
45+
Pass handlers directly to `parse()`.
46+
47+
```ts
48+
import { defaultHandlers, parse } from 'react-docgen';
49+
import myHandler from './myHandler.js';
50+
51+
const docs = parse(code, {
52+
filename: 'Button.tsx',
53+
handlers: [...defaultHandlers, myHandler],
54+
});
55+
```
56+
57+
When `handlers` is provided, the default handlers are not added automatically.
58+
Include `defaultHandlers` yourself if you want to extend the default behavior.
59+
60+
## CLI
61+
62+
The CLI can load a handler by built-in name, package name, or path.
63+
64+
```shell filename="Terminal"
65+
react-docgen --handler ./myHandler.js ./src/Button.tsx
66+
```
67+
68+
Custom handler modules are executed as JavaScript in the current Node.js
69+
process. Only load handlers you trust.
Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,65 @@
1-
import ContentMissing from '@/components/ContentMissing';
2-
31
# Importer
42

5-
<ContentMissing />
3+
Importers resolve imported values for handlers and utilities that need to follow
4+
references across files.
5+
6+
## Signature
7+
8+
```ts
9+
import type { Importer } from 'react-docgen';
10+
11+
const importer: Importer = (path, name, file) => {
12+
return null;
13+
};
14+
```
15+
16+
The importer receives:
17+
18+
- `path`: the import or export declaration being resolved
19+
- `name`: the imported or exported name to find
20+
- `file`: the current [`FileState`](../reference/file-state)
21+
22+
It returns a Babel `NodePath` for the resolved value, or `null` when the value
23+
cannot be resolved.
24+
25+
## Built-in importers
26+
27+
### fsImporter
28+
29+
The default importer. It resolves modules from disk using Node.js resolution
30+
rules, reads the resolved file, parses it, and looks for the requested exported
31+
value.
32+
33+
It supports JavaScript and TypeScript source extensions, including `.js`, `.ts`,
34+
`.tsx`, `.mjs`, `.cjs`, `.mts`, `.cts`, and `.jsx`.
35+
36+
### ignoreImporter
37+
38+
Always returns `null`. Use this when imported values should not be followed.
39+
40+
## makeFsImporter
41+
42+
`makeFsImporter()` creates a new filesystem importer. You can use it to provide
43+
separate caches or a custom module lookup function.
44+
45+
```ts
46+
import { makeFsImporter, parse } from 'react-docgen';
47+
48+
const importer = makeFsImporter();
49+
50+
parse(code, {
51+
filename: '/absolute/path/Button.tsx',
52+
importer,
53+
});
54+
```
55+
56+
## CLI
57+
58+
The CLI can load an importer by built-in name, package name, or path.
59+
60+
```shell filename="Terminal"
61+
react-docgen --importer ignoreImporter ./src/Button.tsx
62+
```
63+
64+
Custom importer modules are executed as JavaScript in the current Node.js
65+
process. Only load importers you trust.
Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,68 @@
1-
import ContentMissing from '@/components/ContentMissing';
2-
31
# Resolver
42

5-
<ContentMissing />
3+
Resolvers decide which AST nodes are React component definitions. Handlers are
4+
then run for each node returned by the resolver.
5+
6+
## Signature
7+
8+
A resolver can be a function:
9+
10+
```ts
11+
import type { ResolverFunction } from 'react-docgen';
12+
13+
const resolver: ResolverFunction = (file) => {
14+
return [];
15+
};
16+
```
17+
18+
Or an object with a `resolve()` method:
19+
20+
```ts
21+
import type { ResolverClass } from 'react-docgen';
22+
23+
const resolver: ResolverClass = {
24+
resolve(file) {
25+
return [];
26+
},
27+
};
28+
```
29+
30+
Both forms return an array of `NodePath<ComponentNode>`.
31+
32+
## FileState
33+
34+
Resolvers receive a [`FileState`](../reference/file-state) object. The resolver
35+
can inspect `file.path`, traverse the AST with `file.traverse()`, or parse and
36+
import related files through the configured importer.
37+
38+
## Built-in resolvers
39+
40+
react-docgen exports these resolver classes through `builtinResolvers`:
41+
42+
- `FindExportedDefinitionsResolver`
43+
- `FindAllDefinitionsResolver`
44+
- `FindAnnotatedDefinitionsResolver`
45+
- `ChainResolver`
46+
47+
## Using a custom resolver
48+
49+
```ts
50+
import { parse } from 'react-docgen';
51+
import myResolver from './myResolver.js';
52+
53+
const docs = parse(code, {
54+
filename: 'Button.tsx',
55+
resolver: myResolver,
56+
});
57+
```
58+
59+
## CLI
60+
61+
The CLI can load a resolver by built-in config name, package name, or path.
62+
63+
```shell filename="Terminal"
64+
react-docgen --resolver ./myResolver.js ./src/Button.tsx
65+
```
66+
67+
Custom resolver modules are executed as JavaScript in the current Node.js
68+
process. Only load resolvers you trust.

packages/website/src/app/docs/getting-started/cli/page.mdx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Tabs } from 'nextra/components';
2+
import { Callout } from 'nextra/components';
23

34
# Getting started with the Command Line Interface (CLI)
45

@@ -70,8 +71,9 @@ react component. The result will be printed to the `stdout` and in case there
7071
are errors or warnings while analyzing the file, these will be printed to
7172
`stderr`.
7273

73-
The result will be an array of [Documentation](../reference/documentation/basic.mdx)
74-
objects, stringified to JSON.
74+
The result will be an object keyed by file path. Each value will be an array of
75+
[Documentation](../reference/documentation/basic.mdx) objects, stringified to
76+
JSON.
7577

7678
```shell filename="Terminal" copy
7779
react-docgen ./src/components/Button.tsx
@@ -98,3 +100,10 @@ react-docgen -o output.json ./src/components/Button.tsx
98100

99101
The CLI supports a lot more advanced options and for a full list checkout the
100102
[reference page](../reference/cli)
103+
104+
<Callout type="warning" emoji="">
105+
Options that load custom modules, such as `--handler`, `--resolver`, and
106+
`--importer`, execute trusted JavaScript code in the current Node.js process.
107+
Do not pass values from untrusted input, user-provided configuration, or
108+
unreviewed shared configuration to these options.
109+
</Callout>

packages/website/src/app/docs/getting-started/nodejs/page.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ import { parse } from 'react-docgen';
3939

4040
const code = `
4141
/** My first component */
42-
export default ({ name }: { name: string }) => <div>{{name}}</div>;
42+
export default ({ name }: { name: string }) => <div>{name}</div>;
4343
`;
4444

45-
const documentation = parse(code);
45+
const documentation = parse(code, { filename: 'index.tsx' });
4646

4747
console.log(documentation);
4848
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
export default {
2+
cli: 'Command Line Interface (CLI)',
23
config: 'Config',
34
api: 'API',
45
documentation: 'Documentation',
56
'file-state': 'FileState',
67
handlers: 'Handlers',
8+
resolvers: 'Resolvers',
79
};

0 commit comments

Comments
 (0)