Skip to content

Commit 2a87acb

Browse files
authored
feat(stories) implement type documentation loader (#84166)
This PR adds a webpack loader that extracts type information which will allow us to add automatic component documentation. The reason we have to use a custom defined loader is because adding this to all .ts imports absolutely cripples the dev experience as all modules are evaluated, not just the ones we have stories for, which balloons dev startup times to a point where it becomes unusable. An alternative approach is to use non ts based inference, which is what storybook does, however given the definition of some of our types like `ButtonProps | ButtonPropsWithAriaLabel` the results are pretty poor. I will follow up with a PR to flag this loader and implement the actual rendering of the type documentation
1 parent 13f87fb commit 2a87acb

File tree

5 files changed

+36
-0
lines changed

5 files changed

+36
-0
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
"query-string": "7.0.1",
148148
"react": "18.2.0",
149149
"react-date-range": "^1.4.0",
150+
"react-docgen-typescript": "^2.2.2",
150151
"react-dom": "18.2.0",
151152
"react-grid-layout": "^1.3.4",
152153
"react-lazyload": "^3.2.1",

static/app/types/type-loader.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '!!type-loader!*' {
2+
const content: Record<string, import('react-docgen-typescript').ComponentDoc>;
3+
export default content;
4+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as docgen from 'react-docgen-typescript';
2+
import type {LoaderContext} from 'webpack';
3+
4+
/**
5+
* Extracts documentation from the modules by running the TS compiler and serializing the types
6+
*
7+
* @param {LoaderContext<any>} this loader context
8+
* @param {string} source source file as string
9+
* @returns {docgen.ComponentDoc}
10+
*/
11+
export default function typeloader(this: LoaderContext<any>, _source: string) {
12+
const callback = this.async();
13+
const entries = docgen.parse(this.resourcePath, {});
14+
15+
if (!entries) {
16+
return callback(null, 'export default {}');
17+
}
18+
19+
return callback(null, `export default ${JSON.stringify(entries)}`);
20+
}

webpack.config.ts

+6
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,12 @@ const appConfig: webpack.Configuration = {
417417
}),
418418
],
419419

420+
resolveLoader: {
421+
alias: {
422+
'type-loader': path.resolve(__dirname, 'static/app/views/stories/type-loader.ts'),
423+
},
424+
},
425+
420426
resolve: {
421427
alias: {
422428
sentry: path.join(staticPrefix, 'app'),

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -10399,6 +10399,11 @@ react-date-range@^1.4.0:
1039910399
react-list "^0.8.13"
1040010400
shallow-equal "^1.2.1"
1040110401

10402+
react-docgen-typescript@^2.2.2:
10403+
version "2.2.2"
10404+
resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c"
10405+
integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==
10406+
1040210407
1040310408
version "18.2.0"
1040410409
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"

0 commit comments

Comments
 (0)