Skip to content

Commit 58d1b00

Browse files
Merge pull request #1 from hipstersmoothie/compiler-options
allow for compilerOption, get features in parity with react-docgen-typescript-loader
2 parents b5139f2 + 1efeefe commit 58d1b00

2 files changed

Lines changed: 58 additions & 29 deletions

File tree

readme.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ const ReactDocgenTypescriptPlugin = require("react-docgen-typescript-plugin");
2121
module.exports = {
2222
plugins: [
2323
new ReactDocgenTypescriptPlugin(),
24-
// or with options
24+
// or with a tsconfig
2525
new ReactDocgenTypescriptPlugin({ tsconfigPath: "./tsconfig.json" }),
26+
// or with options
27+
new ReactDocgenTypescriptPlugin({ jsx: ts.JsxEmit.Preserve }),
2628
],
2729
};
2830
```
@@ -34,6 +36,7 @@ This plugins support all parser options from [react-docgen-typescript](https://g
3436
| Option | Type | Description | Default |
3537
| -------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
3638
| tsconfigPath | string | Specify the location of the `tsconfig.json` to use. | `null` |
39+
| compilerOptions | object | Specify compiler options. Cannot be used with `tsconfigPath` | `null` |
3740
| docgenCollectionName | string or null | Specify the docgen collection name to use. All docgen information will be collected into this global object. Set to `null` to disable. | `STORYBOOK_REACT_CLASSES` |
3841
| setDisplayName | boolean | Set the components' display name. If you want to set display names yourself or are using another plugin to do this, you should disable this option. | `true` |
3942
| typePropName | string | Specify the name of the property for docgen info prop type. | `type` |

src/index.ts

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ import ts from "typescript";
44
import * as docGen from "react-docgen-typescript";
55
import generateDocgenCodeBlock from "react-docgen-typescript-loader/dist/generateDocgenCodeBlock";
66

7-
interface LoaderOptions {
7+
interface TypescriptOptions {
88
/**
99
* Specify the location of the tsconfig.json to use. Can not be used with
1010
* compilerOptions.
1111
**/
1212
tsconfigPath?: string;
13+
/** Specify TypeScript compiler options. Can not be used with tsconfigPath. */
14+
compilerOptions?: ts.CompilerOptions;
15+
}
1316

17+
interface LoaderOptions {
1418
/**
1519
* Specify the docgen collection name to use. All docgen information will
1620
* be collected into this global object. Set to null to disable.
@@ -45,20 +49,23 @@ interface LoaderOptions {
4549
typePropName?: string;
4650
}
4751

48-
export type PluginOptions = docGen.ParserOptions & LoaderOptions;
52+
export type PluginOptions = docGen.ParserOptions &
53+
LoaderOptions &
54+
TypescriptOptions;
4955

5056
interface Module {
5157
userRequest: string;
5258
_source: {
5359
_value: string;
54-
}
60+
};
5561
}
5662

63+
/** Run the docgen parser and inject the result into the output */
5764
function processModule(
5865
parser: docGen.FileParser,
5966
webpackModule: Module,
6067
tsProgram: ts.Program,
61-
loaderOptions: PluginOptions
68+
loaderOptions: Required<LoaderOptions>
6269
) {
6370
if (!webpackModule) {
6471
return;
@@ -77,9 +84,6 @@ function processModule(
7784
filename: webpackModule.userRequest,
7885
source: webpackModule.userRequest,
7986
componentDocs,
80-
typePropName: "type",
81-
docgenCollectionName: "STORYBOOK_REACT_CLASSES",
82-
setDisplayName: true,
8387
...loaderOptions,
8488
}).substring(webpackModule.userRequest.length);
8589

@@ -90,6 +94,21 @@ function processModule(
9094
webpackModule._source._value = source;
9195
}
9296

97+
/** Get the contents of the tsconfig in the system */
98+
function getTSConfigFile(tsconfigPath: string): ts.ParsedCommandLine {
99+
const basePath = path.dirname(tsconfigPath);
100+
const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
101+
102+
return ts.parseJsonConfigFileContent(
103+
configFile.config,
104+
ts.sys,
105+
basePath,
106+
{},
107+
tsconfigPath
108+
);
109+
}
110+
111+
/** Inject typescript docgen information into modules at the end of a build */
93112
export default class DocgenPlugin {
94113
private name = "React Docgen Typescript Plugin";
95114
private options: PluginOptions;
@@ -102,21 +121,27 @@ export default class DocgenPlugin {
102121
const pathRegex = RegExp(`\\${path.sep}src.+\\.tsx`);
103122
const {
104123
tsconfigPath,
105-
propFilter,
106-
componentNameResolver,
107-
shouldExtractLiteralValuesFromEnum,
108-
shouldRemoveUndefinedFromOptional,
109-
savePropValueAsString,
110-
...loaderOptions
124+
docgenCollectionName = "STORYBOOK_REACT_CLASSES",
125+
setDisplayName = true,
126+
typePropName = "type",
127+
compilerOptions: userCompilerOptions,
128+
...docgenOptions
111129
} = this.options;
112-
const docgenOptions = {
113-
propFilter,
114-
componentNameResolver,
115-
shouldExtractLiteralValuesFromEnum,
116-
shouldRemoveUndefinedFromOptional,
117-
savePropValueAsString,
130+
let compilerOptions = {
131+
jsx: ts.JsxEmit.React,
132+
module: ts.ModuleKind.CommonJS,
133+
target: ts.ScriptTarget.Latest,
118134
};
119135

136+
if (userCompilerOptions) {
137+
compilerOptions = { ...compilerOptions, ...userCompilerOptions };
138+
}
139+
140+
if (tsconfigPath) {
141+
const { options } = getTSConfigFile(tsconfigPath);
142+
compilerOptions = { ...compilerOptions, ...options };
143+
}
144+
120145
compiler.hooks.make.tap(this.name, (compilation) => {
121146
compilation.hooks.seal.tap(this.name, () => {
122147
const modulesToProcess: Module[] = [];
@@ -132,20 +157,21 @@ export default class DocgenPlugin {
132157
}
133158
});
134159

160+
const parser =
161+
(tsconfigPath &&
162+
docGen.withCustomConfig(tsconfigPath, docgenOptions)) ||
163+
docGen.withCompilerOptions(compilerOptions, docgenOptions);
135164
const tsProgram = ts.createProgram(
136165
modulesToProcess.map((v) => v.userRequest),
137-
{
138-
jsx: ts.JsxEmit.React,
139-
module: ts.ModuleKind.CommonJS,
140-
target: ts.ScriptTarget.Latest,
141-
}
166+
compilerOptions
142167
);
143-
const parser = tsconfigPath
144-
? docGen.withCustomConfig(tsconfigPath, docgenOptions)
145-
: docGen.withDefaultConfig({});
146168

147169
modulesToProcess.forEach((m) =>
148-
processModule(parser, m, tsProgram, loaderOptions)
170+
processModule(parser, m, tsProgram, {
171+
docgenCollectionName,
172+
setDisplayName,
173+
typePropName,
174+
})
149175
);
150176
});
151177
});

0 commit comments

Comments
 (0)