Skip to content

Commit

Permalink
feat: Improve monorepos by adding support for TS entry points (#1596)
Browse files Browse the repository at this point in the history
  • Loading branch information
Unnvaldr committed Jun 13, 2021
1 parent f95e456 commit 6d215df
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 20 deletions.
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -37,14 +37,16 @@ typedoc package1/index.ts package2/index.ts
### Monorepos / Workspaces

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

:warning: In opposition to project entry points, package entry points are determined relatively to options file if provided.

#### Single npm module

```text
Expand Down
40 changes: 32 additions & 8 deletions src/lib/utils/package-manifest.ts
Expand Up @@ -2,6 +2,7 @@

import glob = require("glob");
import { dirname, join, resolve } from "path";
import { existsSync } from "fs";
import { flatMap } from "./array";

import { readFile } from "./fs";
Expand Down Expand Up @@ -200,29 +201,52 @@ export function getTsEntryPointForPackage(
packageJson: Record<string, unknown>
): string | undefined | typeof ignorePackage {
let packageMain = "index.js"; // The default, per the npm docs.
let packageTypes = null;
if (
hasOwnProperty(packageJson, "main") &&
typeof packageJson.main == "string"
) {
packageMain = packageJson.main;
} else if (
hasOwnProperty(packageJson, "types") &&
typeof packageJson.types == "string"
) {
packageTypes = packageJson.types;
} else if (
hasOwnProperty(packageJson, "typings") &&
typeof packageJson.typings == "string"
) {
packageTypes = packageJson.typings;
}
let jsEntryPointPath = resolve(packageJsonPath, "..", packageMain);
// The jsEntryPointPath from the package manifest can be like a require path.
let entryPointPath = resolve(packageJsonPath, "..", packageMain);
// The entryPointPath from the package manifest can be like a require path.
// It could end with .js, or it could end without .js, or it could be a folder containing an index.js
// We can use require.resolve to let node do its magic.
// Pass an empty `paths` as node_modules locations do not need to be examined
try {
jsEntryPointPath = require.resolve(jsEntryPointPath, { paths: [] });
entryPointPath = require.resolve(entryPointPath, { paths: [] });
if (/\.tsx?$/.test(entryPointPath) && existsSync(entryPointPath)) {
return entryPointPath;
}
} catch (e) {
if (e.code !== "MODULE_NOT_FOUND") {
throw e;
} else {
logger.warn(
`Could not determine the JS entry point for "${packageJsonPath}". Package will be ignored.`
entryPointPath = resolve(
packageJsonPath,
"..",
packageTypes ?? packageMain
);
logger.verbose(e.message);
return ignorePackage;
if (/\.tsx?$/.test(entryPointPath) && existsSync(entryPointPath)) {
return entryPointPath;
} else {
logger.warn(
`Could not determine the entry point for "${packageJsonPath}". Package will be ignored.`
);
logger.verbose(e.message);
return ignorePackage;
}
}
}
return getTsSourceFromJsSource(logger, jsEntryPointPath);
return getTsSourceFromJsSource(logger, entryPointPath);
}
6 changes: 5 additions & 1 deletion src/test/packages.test.ts
Expand Up @@ -14,7 +14,11 @@ describe("Packages support", () => {
const project = app.convert();
equal(
project?.children?.map((r) => r.name),
["typedoc-multi-package-bar", "typedoc-multi-package-foo"]
[
"typedoc-multi-package-bar",
"typedoc-multi-package-baz",
"typedoc-multi-package-foo",
]
);
});

Expand Down
6 changes: 0 additions & 6 deletions src/test/packages/multi-package/packages/bar/dist/index.js

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions src/test/packages/multi-package/packages/bar/index.d.ts
@@ -0,0 +1 @@
export function bar(): void;
1 change: 0 additions & 1 deletion src/test/packages/multi-package/packages/bar/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/packages/multi-package/packages/bar/package.json
@@ -1,5 +1,5 @@
{
"name": "typedoc-multi-package-bar",
"version": "1.0.0",
"main": "dist/index"
"types": "index.d.ts"
}
1 change: 1 addition & 0 deletions src/test/packages/multi-package/packages/baz/index.ts
@@ -0,0 +1 @@
export function baz() {}
5 changes: 5 additions & 0 deletions src/test/packages/multi-package/packages/baz/package.json
@@ -0,0 +1,5 @@
{
"name": "typedoc-multi-package-baz",
"version": "1.0.0",
"main": "index.ts"
}
8 changes: 8 additions & 0 deletions src/test/packages/multi-package/packages/baz/tsconfig.json
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"sourceMap": false,
"inlineSourceMap": true
}
}

0 comments on commit 6d215df

Please sign in to comment.