Skip to content

Instantly share code, notes, and snippets.

@whoisryosuke
Created March 24, 2021 07:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whoisryosuke/225a53a8586874e901d055072b66fb17 to your computer and use it in GitHub Desktop.
Save whoisryosuke/225a53a8586874e901d055072b66fb17 to your computer and use it in GitHub Desktop.
React / NodeJS - Generate React documentation inside MDX files using react-docgen-typescript. Setup for Docusaurus. Run using `node docgen.js`.
const docgen = require('react-docgen-typescript');
const fs = require('fs');
const path = require('path');
const DOCGEN_OPTIONS = {
savePropValueAsString: true,
};
const IGNORE_PATHS = [
'docs',
'node_modules',
'dist',
'__stories__',
'__tests__',
'.git',
];
const ROOT_DIR = './../';
const SIDEBAR_PATH = path.join('./', 'sidebar-components.json');
const DOCS_DIR = './docs/';
const COMPONENT_DOCS_FOLDER_NAME = 'components';
const DOCS_PATH = path.join(DOCS_DIR, COMPONENT_DOCS_FOLDER_NAME);
// Check if the docs path exists, if not, create it
if (!fs.existsSync(DOCS_PATH)) fs.mkdirSync(DOCS_PATH);
const generateDocs = async () => {
// Load components directory
// Go into each folder and find matching files (TSX)
let files = [];
let sidebarNames = [];
const getFiles = (file = '', folder) => {
//ignore files if necessary
if (IGNORE_PATHS.includes(file)) return;
const filePath = path.join(folder ? folder : ROOT_DIR, file);
let isFolder = false;
try {
isFolder = fs.lstatSync(filePath).isDirectory();
} catch (e) {
console.log('couldnt parse file', e);
}
if (isFolder) {
const folderContents = fs.readdirSync(filePath);
folderContents.map((name) => {
const getFolderFiles = getFiles(name, filePath);
return getFolderFiles;
});
}
// Handle file
// Check if TSX
if (file.includes('tsx')) {
files = [...files, filePath];
}
};
getFiles();
console.log('📁 the files', files);
// Run docgen on each file
const docs = files.map((filePath) => {
return docgen.parse(filePath, DOCGEN_OPTIONS);
});
console.log('⚛️ generated docs', docs);
// Loop through final JSON and generate MDX content
// Create MDX files in specified folder (defaults to /components)
// Add page title
// Import props into Props Table component
docs.forEach((doc) => {
if (doc.length < 1) return;
// Add to sidebar
sidebarNames = [
...sidebarNames,
`${COMPONENT_DOCS_FOLDER_NAME}/${doc[0].displayName}`,
];
// Handle MDX file creation
const mdxPath = path.join(DOCS_PATH, `${doc[0].displayName}.mdx`);
console.log('✍️ creating file', mdxPath);
const mdxContent = `${doc[0].description ? doc[0].description : ''}
import PropsTable from './PropsTable';
<PropsTable
propMetaData={${JSON.stringify(doc[0].props, null, 2)}}
/>
`;
fs.writeFileSync(mdxPath, mdxContent);
});
// Update sidebars with new components
// Get sidebar file contents
const sidebar = fs.writeFileSync(
SIDEBAR_PATH,
JSON.stringify(sidebarNames, null, 2),
);
// Replace files
};
generateDocs();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment