Update react-docgen

This commit is contained in:
Felix Kling 2015-02-12 13:46:49 -08:00
parent ba7021f6f8
commit 2f322bf895
6 changed files with 46 additions and 20 deletions

View File

@ -1,9 +1,9 @@
# react-docs-generator # react-docgen
`react-docs-generator` extracts information from React components with which `react-docgen` extracts information from React components with which
you can generate documentation for those components. you can generate documentation for those components.
It uses esprima-fb to parse the provided files into an AST, looks for React It uses [recast][] to parse the provided files into an AST, looks for React
component definitions, and inspects the `propTypes` and `getDefaultProps` component definitions, and inspects the `propTypes` and `getDefaultProps`
declarations. The output is a JSON blob with the extracted information. declarations. The output is a JSON blob with the extracted information.
@ -16,18 +16,18 @@ is a limit to what is statically analyzable.
Install the module directly from npm: Install the module directly from npm:
``` ```
npm install -g react-docs-generator npm install -g react-docgen
``` ```
## CLI ## CLI
Installing the module adds a `react-docs` executable which allows you do convert Installing the module adds a `react-docgen` executable which allows you do convert
a single file, multiple files or an input stream. We are trying to make the a single file, multiple files or an input stream. We are trying to make the
executable as versatile as possible so that it can be integrated into many executable as versatile as possible so that it can be integrated into many
workflows. workflows.
``` ```
Usage: react-docs [path]... [options] Usage: react-docgen [path]... [options]
path A component file or directory. If no path is provided it reads from stdin. path A component file or directory. If no path is provided it reads from stdin.
@ -46,7 +46,7 @@ If a directory is passed, it is recursively traversed.
The tool can also be used programmatically to extract component information: The tool can also be used programmatically to extract component information:
```js ```js
var reactDocs = require('react-docs-generator'); var reactDocs = require('react-docgen');
var componentInfo reactDocs.parseSource(src); var componentInfo reactDocs.parseSource(src);
``` ```
@ -160,6 +160,7 @@ The structure of the JSON blob / JavaScript object is as follows:
"type": { "type": {
"name": "<typeName>", "name": "<typeName>",
["value": <typeValue>] ["value": <typeValue>]
["raw": string]
}, },
"required": boolean, "required": boolean,
"description": string, "description": string,
@ -173,3 +174,5 @@ The structure of the JSON blob / JavaScript object is as follows:
["composes": <componentNames>] ["composes": <componentNames>]
} }
``` ```
[recast]: https://github.com/benjamn/recast

View File

@ -10,7 +10,7 @@
*/ */
var argv = require('nomnom') var argv = require('nomnom')
.script('react-docs') .script('react-docgen')
.help( .help(
'Extract meta information from React components.\n' + 'Extract meta information from React components.\n' +
'If a directory is passed, it is recursively traversed.' 'If a directory is passed, it is recursively traversed.'

View File

@ -17,6 +17,7 @@ type PropDescriptor = {
type?: { type?: {
name: string; name: string;
value?: any; value?: any;
raw?: string;
}; };
required?: boolean; required?: boolean;
defaultValue?: any; defaultValue?: any;

View File

@ -152,7 +152,7 @@ describe('React documentation parser', function() {
expect(result).toEqual(expectedResult); expect(result).toEqual(expectedResult);
}); });
it.only('detects complex prop types', function() { it('detects complex prop types', function() {
var source = getSource([ var source = getSource([
'{', '{',
' propTypes: {', ' propTypes: {',
@ -197,9 +197,10 @@ describe('React documentation parser', function() {
oneOfType_custom_prop: { oneOfType_custom_prop: {
type: { type: {
name:'union', name:'union',
value: [ value: [{
{name: 'custom'} name: 'custom',
] raw: 'xyz'
}]
}, },
required: false required: false
}, },
@ -231,7 +232,10 @@ describe('React documentation parser', function() {
type: { type: {
name: 'shape', name: 'shape',
value: { value: {
foo: {name: 'custom'}, foo: {
name: 'custom',
raw: 'xyz'
},
} }
}, },
required: false required: false
@ -368,7 +372,8 @@ describe('React documentation parser', function() {
var source = getSource([ var source = getSource([
'{', '{',
' propTypes: {', ' propTypes: {',
' custom_prop: function() {}', ' custom_prop: function() {},',
' custom_prop2: () => {}',
' }', ' }',
'}' '}'
].join('\n')); ].join('\n'));
@ -377,7 +382,17 @@ describe('React documentation parser', function() {
description: '', description: '',
props: { props: {
custom_prop: { custom_prop: {
type: {name: 'custom'}, type: {
name: 'custom',
raw: 'function() {}'
},
required: false
},
custom_prop2: {
type: {
name: 'custom',
raw: '() => {}'
},
required: false required: false
} }
} }
@ -409,7 +424,10 @@ describe('React documentation parser', function() {
required: false required: false
}, },
custom_propB: { custom_propB: {
type: {name: 'custom'}, type: {
name: 'custom',
raw: 'Prop.bool.isRequired'
},
required: false required: false
} }
} }

View File

@ -30,7 +30,7 @@ function getDefaultValue(path) {
} else { } else {
path = resolveToValue(path); path = resolveToValue(path);
node = path.node; node = path.node;
defaultValue = expressionTo.String(path); defaultValue = recast.print(path).code;
} }
if (typeof defaultValue !== 'undefined') { if (typeof defaultValue !== 'undefined') {
return { return {

View File

@ -19,9 +19,10 @@ var expressionTo = require('../utils/expressionTo');
var getNameOrValue = require('../utils/getNameOrValue'); var getNameOrValue = require('../utils/getNameOrValue');
var getPropertyName = require('../utils/getPropertyName'); var getPropertyName = require('../utils/getPropertyName');
var isReactModuleName = require('../utils/isReactModuleName'); var isReactModuleName = require('../utils/isReactModuleName');
var recast = require('recast');
var resolveToModule = require('../utils/resolveToModule'); var resolveToModule = require('../utils/resolveToModule');
var resolveToValue = require('../utils/resolveToValue'); var resolveToValue = require('../utils/resolveToValue');
var types = require('recast').types.namedTypes; var types = recast.types.namedTypes;
var simplePropTypes = { var simplePropTypes = {
array: 1, array: 1,
@ -146,8 +147,11 @@ var propTypes = {
*/ */
function getPropType(path) { function getPropType(path) {
var node = path.node; var node = path.node;
if (types.FunctionExpression.check(node) || !isPropTypesExpression(path)) { if (types.Function.check(node) || !isPropTypesExpression(path)) {
return {name: 'custom'}; return {
name: 'custom',
raw: recast.print(path).code
};
} }
var expressionParts = []; var expressionParts = [];