Skip to content

Commit 6d215df

Browse files
authored
feat: Improve monorepos by adding support for TS entry points (#1596)
1 parent f95e456 commit 6d215df

File tree

11 files changed

+57
-20
lines changed

11 files changed

+57
-20
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@ typedoc package1/index.ts package2/index.ts
3737
### Monorepos / Workspaces
3838

3939
If your codebase is comprised of one or more npm packages, you can pass the paths to these
40-
packages and TypeDoc will attempt to determine entry points from your `package.json`'s `main`
41-
property (or its default value `index.js`).
40+
packages and TypeDoc will attempt to determine entry points based on `package.json`'s `main`
41+
property (with default value `index.js`) and if it wasn't found, based on `types` property.
4242
If any of the packages given are the root of an [npm Workspace](https://docs.npmjs.com/cli/v7/using-npm/workspaces)
4343
or a [Yarn Workspace](https://classic.yarnpkg.com/en/docs/workspaces/) TypeDoc will find all
4444
the `workspaces` defined in the `package.json`.
4545
This mode requires sourcemaps in your JS entry points, in order to find the TS entry points.
4646
Supports wildcard paths in the same fashion as those found in npm or Yarn workspaces.
4747

48+
:warning: In opposition to project entry points, package entry points are determined relatively to options file if provided.
49+
4850
#### Single npm module
4951

5052
```text

src/lib/utils/package-manifest.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import glob = require("glob");
44
import { dirname, join, resolve } from "path";
5+
import { existsSync } from "fs";
56
import { flatMap } from "./array";
67

78
import { readFile } from "./fs";
@@ -200,29 +201,52 @@ export function getTsEntryPointForPackage(
200201
packageJson: Record<string, unknown>
201202
): string | undefined | typeof ignorePackage {
202203
let packageMain = "index.js"; // The default, per the npm docs.
204+
let packageTypes = null;
203205
if (
204206
hasOwnProperty(packageJson, "main") &&
205207
typeof packageJson.main == "string"
206208
) {
207209
packageMain = packageJson.main;
210+
} else if (
211+
hasOwnProperty(packageJson, "types") &&
212+
typeof packageJson.types == "string"
213+
) {
214+
packageTypes = packageJson.types;
215+
} else if (
216+
hasOwnProperty(packageJson, "typings") &&
217+
typeof packageJson.typings == "string"
218+
) {
219+
packageTypes = packageJson.typings;
208220
}
209-
let jsEntryPointPath = resolve(packageJsonPath, "..", packageMain);
210-
// The jsEntryPointPath from the package manifest can be like a require path.
221+
let entryPointPath = resolve(packageJsonPath, "..", packageMain);
222+
// The entryPointPath from the package manifest can be like a require path.
211223
// It could end with .js, or it could end without .js, or it could be a folder containing an index.js
212224
// We can use require.resolve to let node do its magic.
213225
// Pass an empty `paths` as node_modules locations do not need to be examined
214226
try {
215-
jsEntryPointPath = require.resolve(jsEntryPointPath, { paths: [] });
227+
entryPointPath = require.resolve(entryPointPath, { paths: [] });
228+
if (/\.tsx?$/.test(entryPointPath) && existsSync(entryPointPath)) {
229+
return entryPointPath;
230+
}
216231
} catch (e) {
217232
if (e.code !== "MODULE_NOT_FOUND") {
218233
throw e;
219234
} else {
220-
logger.warn(
221-
`Could not determine the JS entry point for "${packageJsonPath}". Package will be ignored.`
235+
entryPointPath = resolve(
236+
packageJsonPath,
237+
"..",
238+
packageTypes ?? packageMain
222239
);
223-
logger.verbose(e.message);
224-
return ignorePackage;
240+
if (/\.tsx?$/.test(entryPointPath) && existsSync(entryPointPath)) {
241+
return entryPointPath;
242+
} else {
243+
logger.warn(
244+
`Could not determine the entry point for "${packageJsonPath}". Package will be ignored.`
245+
);
246+
logger.verbose(e.message);
247+
return ignorePackage;
248+
}
225249
}
226250
}
227-
return getTsSourceFromJsSource(logger, jsEntryPointPath);
251+
return getTsSourceFromJsSource(logger, entryPointPath);
228252
}

src/test/packages.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ describe("Packages support", () => {
1414
const project = app.convert();
1515
equal(
1616
project?.children?.map((r) => r.name),
17-
["typedoc-multi-package-bar", "typedoc-multi-package-foo"]
17+
[
18+
"typedoc-multi-package-bar",
19+
"typedoc-multi-package-baz",
20+
"typedoc-multi-package-foo",
21+
]
1822
);
1923
});
2024

src/test/packages/multi-package/packages/bar/dist/index.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/test/packages/multi-package/packages/bar/dist/index.js.map

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export function bar(): void;

src/test/packages/multi-package/packages/bar/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"name": "typedoc-multi-package-bar",
33
"version": "1.0.0",
4-
"main": "dist/index"
4+
"types": "index.d.ts"
55
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export function baz() {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "typedoc-multi-package-baz",
3+
"version": "1.0.0",
4+
"main": "index.ts"
5+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"sourceMap": false,
6+
"inlineSourceMap": true
7+
}
8+
}

0 commit comments

Comments
 (0)