strothj / react-docgen-typescript-loader

Webpack loader to generate docgen information from Typescript React components.
Other
360 stars 47 forks source link

Discrepancy with ts-loader in monorepos #100

Open daniel-ac-martin opened 4 years ago

daniel-ac-martin commented 4 years ago

When organising your project as a monorepo (i.e. you have components above your application for which you would like to collect prop information) you are likely to be met with an error saying that prop information could not be collected.

Consider the following project layout:

./apps/docs/index.js
./apps/docs/tsconfig.json
./apps/docs/webpack.config.js
./components/MyComponent/MyComponent.tsx
./components/MyComponent/package.json
./tsconfig.json

Let's say that react-docgen-typescript-loader is set up alongside ts-loader (although I believe the same argument would hold for babel-loader) according to the README it would make sense to reference the same tsconfig that is passed to babel-loader (or at least the same as the one that would be defaulted to). i.e. ./apps/docs/tsconfig.json. However, if this is done ./components/MyComponent/MyComponent.tsx will NOT be processed and so it will be impossible to display the props for the component you would like to document.

A (partial?) workaround for this problem is to instead reference ./tsconfig.json in the root of the monorepo.

This behaviour is unintuitive as ts-loader has no problem processing the file.

Why does this happen?

Whilst ts-loader works the way a normal webpack loader does and processes the source that is given to it by webpack, react-docgen-typescript-loader instead attempts to re-read the file via Typescript which refuses to do so on the grounds that it considers the the file to be out of scope, being that it is located above the tsconfig.json file.

The reason this is the case is that react-docgen-typescript expects a filename rather than a string of source code. I'm not sure how one would fix this problem beyond convincing the react-docgen-typescript maintainers to support a different way of consuming their library or forking.

As monorepos become more popular it might at least be worth documenting this scenario in the README. I suspect the workaround is reasonably good, simply because it is possible to store the majority of the TypeScript configuration in the root of the monorepo and this is probably desirable in most cases.

Notes (just for completeness and posterity)

  1. The source code is requested from Typescript (and filtered out of being processed when Typescript decides the file is out of scope) here: https://github.com/styleguidist/react-docgen-typescript/blob/master/src/parser.ts#L1088-L1092
  2. A source file seems to be out of scope when it does not appear in the fileNames property of the tsConfigFile object here: https://github.com/strothj/react-docgen-typescript-loader/blob/663b94a41004ef490928fca67ab7306429d49379/src/loader.ts#L97
  3. The fileNames property appears to be set here: https://github.com/microsoft/TypeScript/blob/f628bf8e245dde6e32bd47665736c5f7f5990332/src/compiler/commandLineParser.ts#L2354-L2358 And is populated based on the basePath which must be set correctly in order to properly process the tsconfig.json file and is set here: https://github.com/strothj/react-docgen-typescript-loader/blob/663b94a41004ef490928fca67ab7306429d49379/src/loader.ts#L152