Skip to content
Merged

Docs #1091

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/react-docgen-cli/src/commands/parse/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,18 @@ program
'--resolver <resolvers>',
`Built-in resolver config (${Object.values(ResolverConfigs).join(
', ',
)}), 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.`,
)}), 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.`,
collect,
defaultResolvers,
)
.option(
'--importer <importer>',
'Built-in importer name (fsImport, ignoreImporter), package name or path to a module that exports an importer.',
'Built-in importer name (fsImporter, ignoreImporter), package name or path to a trusted module that exports an importer.',
'fsImporter',
)
.option(
'--handler <handlers>',
'Comma separated list of handlers to use. Can also be used multiple times. When used, no default handlers will be added.',
'Comma separated list of trusted handlers to use. Can also be used multiple times. When used, no default handlers will be added.',
collect,
defaultHandlers,
)
Expand All @@ -109,7 +109,7 @@ program

let finalIgnores = ignore;

// Push the default ignores unless the --no-default-ignore is set
// Push the default ignores unless the --no-default-ignores is set
if (defaultIgnores === true && ignore !== defaultIgnoreGlobs) {
finalIgnores.push(...defaultIgnoreGlobs);
} else if (defaultIgnores === false && ignore === defaultIgnoreGlobs) {
Expand Down
55 changes: 52 additions & 3 deletions packages/website/src/app/docs/extending/architecture/page.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,54 @@
import ContentMissing from '@/components/ContentMissing';

# Architecture

<ContentMissing />
react-docgen works in four steps:

1. Parse the source code with Babel.
2. Build a [`FileState`](../reference/file-state) object around the AST.
3. Run a resolver to find React component definitions.
4. Run handlers on each component definition and build the final documentation.

## Parsing

`parse()` accepts source code and a config object. The source is parsed with
Babel. If no Babel config file is found, react-docgen applies default parser
plugins for JSX and either TypeScript or Flow.

TypeScript syntax is enabled by default for filenames ending in `.ts`, `.tsx`,
`.mts`, or `.cts`. Other files use Flow syntax by default.

## FileState

`FileState` stores the AST, root program path, source code, parser options, and
the configured importer. It also provides helpers used by resolvers, handlers,
and utilities:

- `file.traverse()` to walk the AST
- `file.import()` to resolve imported values
- `file.parse()` to parse another file with the same importer

## Resolvers

The resolver receives the `FileState` and returns component definition paths.

The default parser config uses a chain of built-in resolvers to find exported
components and annotated components. Custom resolvers can replace that behavior.

## Handlers

Handlers receive a `DocumentationBuilder` and one component definition. Each
handler adds one kind of information, such as prop types, default props, display
name, or component methods.

When all handlers have run, the builder produces a `Documentation` object.

## Importers

Importers are used when react-docgen needs to follow imports. The default
filesystem importer resolves imported source files from disk. The ignore
importer disables cross-file resolution.

## Output

The JavaScript API returns an array of `Documentation` objects. The CLI returns
a JSON object keyed by file path, where each value is an array of
`Documentation` objects for that file.
70 changes: 67 additions & 3 deletions packages/website/src/app/docs/extending/handler/page.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,69 @@
import ContentMissing from '@/components/ContentMissing';

# Handler

<ContentMissing />
Handlers extract information from every component found by the resolver. A
handler receives a `DocumentationBuilder` and the Babel `NodePath` for the
component definition.

```ts
import type { Handler } from 'react-docgen';

const handler: Handler = (documentation, componentDefinition) => {
documentation.set('customValue', componentDefinition.node.type);
};
```

## Signature

```ts
type Handler = (
documentation: DocumentationBuilder,
componentDefinition: NodePath<ComponentNode>,
) => void;
```

## Writing data

Use the methods on `DocumentationBuilder` to add data.

```ts
documentation.set('displayName', 'Button');
documentation.addComposes('./otherProps');

const prop = documentation.getPropDescriptor('label');
prop.description = 'Text shown inside the button.';
```

For context-related handlers, use:

```ts
documentation.getContextDescriptor('theme');
documentation.getChildContextDescriptor('theme');
```

## Using a custom handler

Pass handlers directly to `parse()`.

```ts
import { defaultHandlers, parse } from 'react-docgen';
import myHandler from './myHandler.js';

const docs = parse(code, {
filename: 'Button.tsx',
handlers: [...defaultHandlers, myHandler],
});
```

When `handlers` is provided, the default handlers are not added automatically.
Include `defaultHandlers` yourself if you want to extend the default behavior.

## CLI

The CLI can load a handler by built-in name, package name, or path.

```shell filename="Terminal"
react-docgen --handler ./myHandler.js ./src/Button.tsx
```

Custom handler modules are executed as JavaScript in the current Node.js
process. Only load handlers you trust.
66 changes: 63 additions & 3 deletions packages/website/src/app/docs/extending/importer/page.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,65 @@
import ContentMissing from '@/components/ContentMissing';

# Importer

<ContentMissing />
Importers resolve imported values for handlers and utilities that need to follow
references across files.

## Signature

```ts
import type { Importer } from 'react-docgen';

const importer: Importer = (path, name, file) => {
return null;
};
```

The importer receives:

- `path`: the import or export declaration being resolved
- `name`: the imported or exported name to find
- `file`: the current [`FileState`](../reference/file-state)

It returns a Babel `NodePath` for the resolved value, or `null` when the value
cannot be resolved.

## Built-in importers

### fsImporter

The default importer. It resolves modules from disk using Node.js resolution
rules, reads the resolved file, parses it, and looks for the requested exported
value.

It supports JavaScript and TypeScript source extensions, including `.js`, `.ts`,
`.tsx`, `.mjs`, `.cjs`, `.mts`, `.cts`, and `.jsx`.

### ignoreImporter

Always returns `null`. Use this when imported values should not be followed.

## makeFsImporter

`makeFsImporter()` creates a new filesystem importer. You can use it to provide
separate caches or a custom module lookup function.

```ts
import { makeFsImporter, parse } from 'react-docgen';

const importer = makeFsImporter();

parse(code, {
filename: '/absolute/path/Button.tsx',
importer,
});
```

## CLI

The CLI can load an importer by built-in name, package name, or path.

```shell filename="Terminal"
react-docgen --importer ignoreImporter ./src/Button.tsx
```

Custom importer modules are executed as JavaScript in the current Node.js
process. Only load importers you trust.
69 changes: 66 additions & 3 deletions packages/website/src/app/docs/extending/resolver/page.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
import ContentMissing from '@/components/ContentMissing';

# Resolver

<ContentMissing />
Resolvers decide which AST nodes are React component definitions. Handlers are
then run for each node returned by the resolver.

## Signature

A resolver can be a function:

```ts
import type { ResolverFunction } from 'react-docgen';

const resolver: ResolverFunction = (file) => {
return [];
};
```

Or an object with a `resolve()` method:

```ts
import type { ResolverClass } from 'react-docgen';

const resolver: ResolverClass = {
resolve(file) {
return [];
},
};
```

Both forms return an array of `NodePath<ComponentNode>`.

## FileState

Resolvers receive a [`FileState`](../reference/file-state) object. The resolver
can inspect `file.path`, traverse the AST with `file.traverse()`, or parse and
import related files through the configured importer.

## Built-in resolvers

react-docgen exports these resolver classes through `builtinResolvers`:

- `FindExportedDefinitionsResolver`
- `FindAllDefinitionsResolver`
- `FindAnnotatedDefinitionsResolver`
- `ChainResolver`

## Using a custom resolver

```ts
import { parse } from 'react-docgen';
import myResolver from './myResolver.js';

const docs = parse(code, {
filename: 'Button.tsx',
resolver: myResolver,
});
```

## CLI

The CLI can load a resolver by built-in config name, package name, or path.

```shell filename="Terminal"
react-docgen --resolver ./myResolver.js ./src/Button.tsx
```

Custom resolver modules are executed as JavaScript in the current Node.js
process. Only load resolvers you trust.
13 changes: 11 additions & 2 deletions packages/website/src/app/docs/getting-started/cli/page.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Tabs } from 'nextra/components';
import { Callout } from 'nextra/components';

# Getting started with the Command Line Interface (CLI)

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

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

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

The CLI supports a lot more advanced options and for a full list checkout the
[reference page](../reference/cli)

<Callout type="warning" emoji="">
Options that load custom modules, such as `--handler`, `--resolver`, and
`--importer`, execute trusted JavaScript code in the current Node.js process.
Do not pass values from untrusted input, user-provided configuration, or
unreviewed shared configuration to these options.
</Callout>
4 changes: 2 additions & 2 deletions packages/website/src/app/docs/getting-started/nodejs/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ import { parse } from 'react-docgen';

const code = `
/** My first component */
export default ({ name }: { name: string }) => <div>{{name}}</div>;
export default ({ name }: { name: string }) => <div>{name}</div>;
`;

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

console.log(documentation);
```
Expand Down
2 changes: 2 additions & 0 deletions packages/website/src/app/docs/reference/_meta.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export default {
cli: 'Command Line Interface (CLI)',
config: 'Config',
api: 'API',
documentation: 'Documentation',
'file-state': 'FileState',
handlers: 'Handlers',
resolvers: 'Resolvers',
};
Loading
Loading