Skip to content

Commit

Permalink
fix(docz-core): react docgen typescript performance
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Feb 22, 2019
1 parent 2fee5ef commit 2967e7c
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 41 deletions.
10 changes: 5 additions & 5 deletions core/docz-core/src/bundler/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ export const createConfig = (args: Args, env: Env) => async (hooks: Hooks) => {
* loaders
*/

const jsBabelRc = await getBabelConfig(args, env)
const tsBabelRc = await getBabelConfig(args, env, true)
const jsBabelrc = await getBabelConfig(args, env)
const tsBabelrc = await getBabelConfig(args, env, true)

config.when(args.sourcemaps, cfg => loaders.sourceMaps(cfg, args))
loaders.js(config, args, jsBabelRc)
loaders.mdx(config, args, jsBabelRc)
loaders.js(config, args, jsBabelrc)
loaders.mdx(config, args, jsBabelrc)
loaders.images(config)
loaders.svg(config)
loaders.media(config)
Expand Down Expand Up @@ -154,7 +154,7 @@ export const createConfig = (args: Args, env: Env) => async (hooks: Hooks) => {
.prepend('.tsx')
.end()

loaders.ts(cfg, args, tsBabelRc)
loaders.ts(cfg, args, tsBabelrc)
})

/**
Expand Down
5 changes: 1 addition & 4 deletions core/docz-core/src/bundler/server.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import chalk from 'chalk'
import logger from 'signale'
import WebpackDevServer from 'webpack-dev-server'

import { Configuration as Config } from 'webpack'
import PrettyError from 'pretty-error'

import { devServerConfig } from './devserver'
import { Config as Args } from '../config/argv'
import { ServerHooks as Hooks } from '../lib/Bundler'

const pe = new PrettyError()
const createCompiler = (config: Config) =>
new Promise<any>(resolve => {
try {
resolve(require('webpack')(config))
} catch (err) {
logger.fatal(chalk.red('Failed to compile.'))
pe.render(err)
logger.error(err)
process.exit(1)
}
})
Expand Down
7 changes: 2 additions & 5 deletions core/docz-core/src/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Arguments } from 'yargs'
import * as logger from 'signale'
import * as envDotProp from 'env-dot-prop'
import PrettyError from 'pretty-error'

import { Plugin } from '../lib/Plugin'
import { Entries } from '../lib/Entries'
Expand All @@ -9,7 +9,6 @@ import { parseConfig } from '../config/docz'
import { bundler as webpack } from '../bundler'
import * as states from '../states'

const pe = new PrettyError()
export const build = async (args: Arguments<any>) => {
const env = envDotProp.get('node.env')
const config = await parseConfig(args)
Expand All @@ -26,14 +25,12 @@ export const build = async (args: Arguments<any>) => {
try {
await Entries.writeApp(config, true)
await dataServer.start()

await run('onPreBuild', config)
await bundler.build(bundlerConfig)

await run('onPostBuild', config)
dataServer.close()
} catch (err) {
pe.render(err)
logger.error(err)
process.exit(1)
dataServer.close()
}
Expand Down
4 changes: 1 addition & 3 deletions core/docz-core/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ process.setMaxListeners(Infinity)
import { Arguments } from 'yargs'
import * as logger from 'signale'
import * as envDotProp from 'env-dot-prop'
import PrettyError from 'pretty-error'

import { Entries } from '../lib/Entries'
import { DataServer } from '../lib/DataServer'
Expand All @@ -13,7 +12,6 @@ import { onSignal } from '../utils/on-signal'
import { bundler as webpack } from '../bundler'
import * as states from '../states'

const pe = new PrettyError()
export const dev = async (args: Arguments<any>) => {
const env = envDotProp.get('node.env')
const config = await parseConfig(args)
Expand All @@ -28,7 +26,7 @@ export const dev = async (args: Arguments<any>) => {
await Entries.writeApp(config, true)
} catch (err) {
logger.fatal('Failed to build your files')
pe.render(err)
logger.error(err)
process.exit(1)
}

Expand Down
6 changes: 2 additions & 4 deletions core/docz-core/src/lib/Entries.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import * as path from 'path'
import * as fs from 'fs-extra'
import * as logger from 'signale'
import { parseMdx } from 'docz-utils/lib/mdast'
import { touch, compiled } from 'docz-utils/lib/fs'
import glob from 'fast-glob'
import PrettyError from 'pretty-error'

import * as paths from '../config/paths'

Expand All @@ -14,7 +14,6 @@ import { getRepoEditUrl } from '../utils/repo-info'

export const fromTemplates = (file: string) => path.join(paths.templates, file)

const pe = new PrettyError()
const mapToObj = (map: Map<any, any>) =>
Array.from(map.entries()).reduce(
(obj, [key, value]) => ({ ...obj, [`${key}`]: value }),
Expand Down Expand Up @@ -100,8 +99,7 @@ export class Entries {
...rest,
}
} catch (err) {
console.log(err)
config.debug && pe.render(err)
logger.error(err)
return null
}
}
Expand Down
11 changes: 7 additions & 4 deletions core/docz-core/src/states/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import chokidar from 'chokidar'
import fastglob from 'fast-glob'
import { State, Params } from '../lib/DataServer'
import { flatten, get } from 'lodash/fp'
import { Signale } from 'signale'

import * as paths from '../config/paths'
import { Config } from '../config/argv'
Expand All @@ -21,7 +22,6 @@ const initial = (config: Config) => async (p: Params) => {
const pattern = getPattern(config.typescript)
const files = await fastglob<string>(pattern, { cwd: paths.root })
const metadata = await docgen(files, config)

p.setState('props', flatten(mapToArray(metadata)))
}

Expand All @@ -31,7 +31,6 @@ const add = (p: Params, config: Config) => async (filepath: string) => {
const keys = metadata.map(item => item.key)
const filtered = prev.filter((item: any) => keys.indexOf(item.key) === -1)
const next = flatten(filtered.concat([metadata]))

p.setState('props', next)
}

Expand All @@ -55,10 +54,14 @@ export const state = (config: Config): State => {
return {
id: 'props',
start: async params => {
const interactive = new Signale({ interactive: true, scope: 'props' })
interactive.await(
'Parsing initial props from your components (this could take a while)'
)
const addInitial = initial(config)

await addInitial(params)
watcher.on('add', add(params, config))
interactive.success('Props parsed successfuly')

watcher.on('change', add(params, config))
watcher.on('unlink', remove(params))
},
Expand Down
59 changes: 43 additions & 16 deletions core/docz-core/src/utils/docgen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,60 @@ import externalProptypesHandler from 'react-docgen-external-proptypes-handler'
import actualNameHandler from 'react-docgen-actual-name-handler'
import reactDocgenTs from 'react-docgen-typescript'
import reactDocgen from 'react-docgen'
import PrettyError from 'pretty-error'
import ts from 'typescript'

import * as paths from '../config/paths'
import { Config } from '../config/argv'

const pe = new PrettyError()
const fileFullPath = (filepath: string) => path.join(paths.root, filepath)

const tsProgram = (files: string[]) =>
ts.createProgram(files, {
jsx: ts.JsxEmit.React,
module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.Latest,
})

const tsDocgen = (config: Config, tsconfig: string, program: ts.Program) => (
filepath: string
) =>
new Promise((resolve, reject) => {
try {
const opts = {
propFilter(prop: any): any {
if (prop.parent == null) return true
const propFilter = config.docgenConfig.propFilter
const val = propFilter && isFunction(propFilter) && propFilter(prop)
return !prop.parent.fileName.includes('node_modules') || Boolean(val)
},
}

const docs = reactDocgenTs
.withCustomConfig(tsconfig, opts)
.parseWithProgramProvider(filepath, () => program)

resolve(docs)
} catch (err) {
reject(err)
}
})

const tsParser = async (files: string[], config: Config) => {
const tsConfigPath = await findUp('tsconfig.json', { cwd: paths.root })
if (!tsConfigPath) return {}

const program = tsProgram(files)
const parse = tsDocgen(config, tsConfigPath, program)
try {
const { parse } = reactDocgenTs.withCustomConfig(tsConfigPath, {
propFilter(prop: any, component: any): any {
if (prop.parent == null) return true
const propFilter = config.docgenConfig.propFilter
const val = propFilter && isFunction(propFilter) && propFilter(prop)
return !prop.parent.fileName.includes('node_modules') || Boolean(val)
},
})
const operations = await Promise.all(
files.map(async filepath => ({
[fileFullPath(filepath)]: await parse(filepath),
}))
)

return files
.map(filepath => ({ [fileFullPath(filepath)]: parse(filepath) }))
.reduce((obj, val) => ({ ...obj, ...val }), {})
return operations.reduce((obj, val) => ({ ...obj, ...val }), {})
} catch (err) {
logger.fatal('Error parsing static types.')
pe.render(err)
logger.error(err)
return {}
}
}
Expand All @@ -58,7 +84,8 @@ const jsParser = (files: string[], config: Config) => {
const data = reactDocgen.parse(code, resolver, handlers)
memo[fileFullPath(filepath)] = data
} catch (err) {
pe.render(err)
logger.fatal('Error parsing static types.')
logger.error(err)
}

return memo
Expand Down

0 comments on commit 2967e7c

Please sign in to comment.