rushstack icon indicating copy to clipboard operation
rushstack copied to clipboard

[api-extractor] Multiple Root/Source Entry Points in extraction

Open donahut opened this issue 6 years ago • 6 comments

Currently, a basic api-extractor.json looks something like:

{
  "$schema": "https://dev.office.com/json-schemas/api-extractor/api-extractor.schema.json",
  "compiler" : {
    "configType": "tsconfig",
    "rootFolder": "."
  },
  "project": {
    "entryPointSourceFile": "lib/index.d.ts"
  }
}

which works great for repos that only contain one src root. However, it'd be great if it were possible to supply multiple projects/roots/entry points to better support monorepos. Perhaps you get this for free with Rush as your monorepo solution (?) or the suggested approach would be to roll extraction/doc generation at a per package level via their respective gulp task (or similar), but it'd be quite handy to be able to accomplish it from the CLI as well.

donahut avatar May 20 '18 00:05 donahut

In our monorepo, each project has its own package.json file and can be built/published independently of the others. We run API Extractor separately on each project as part of its build. In our use case libraries generally have a single entry point.

We understand that there are cases however where it makes sense to have multiple entry points for a single package. In this case, consumers use path-based imports (import * as X from "library/entry-point";). With the right configuration to identify these entry points, API Extractor could support this. We will implement it eventually, but it's fairly complicated for the .d.ts rollup feature to support.

If you don't need rollups, as a workaround you can simply create a fake entry point that reexports all your real entry points. That will work reasonably well for the API report and documentation features.

octogonz avatar May 20 '18 00:05 octogonz

each project has its own package.json file and can be built/published independently of the others. We run API Extractor separately on each project as part of its build.

This is true of ours as well (Lerna-based) and in the past we had done just that. In the switch from JSDocs to Typedocs we had moved to a single-shot docs generation pass as a separate step over the monorepo rather than per package, which is partially what spawned the question. Though, given what AE yields is more than just docs, it's probably better to just return to the per-package approach to reap the full benefit.

Great idea with the fake entrypoint idea though, that'll be useful for making a quick prototype of what an AE-based doc solution would look like for us.

donahut avatar May 20 '18 01:05 donahut

Makes sense. Philosophically one of our principals has been that projects in the monorepo should remain isolated/decoupled, so they can be moved between repos easily. So we try to avoid any operations that process multiple projects as a global operation. This also makes incremental builds easier to implement. This summer we are expanding Rush to shard its builds across multiple lab machines, which makes this isolation even more fundamental. Just something to think about...

octogonz avatar May 20 '18 17:05 octogonz

FYI Api Extractor 7 will introduce an ApiEntryPoint object in the api.json file, which is a first step towards supporting this. We also included support for API Entry points in the TSDoc declaration reference syntax.

octogonz avatar Oct 31 '18 00:10 octogonz

If you don't need rollups, as a workaround you can simply create a fake entry point that reexports all your real entry points. That will work reasonably well for the API report and documentation features.

One issue with this approach is that the generated documentation doesn't have any indication of how the different symbols are spread across various entry points. It looks like they were all defined in the same module. This would be a viable solution if API Extractor could handle wildcard exports like the following:

// file: fake-entrypoint.ts

export * as app from './app/index';
export * as auth from './auth/index';

hiranya911 avatar May 14 '21 21:05 hiranya911

Hi @octogonz

When running API Extractor for each library separately in the monorepo, to my surprise, in the API report of certain library I get full declarations of the types that were imported from my other libraries. For example the report for a certain library looks like this:

// Note: X was just imported from @my/other-library
interface X {
 foo: number;
 bar: string;
}

export interface Y extends X { ... }

Instead, I would rather expect getting in the report just import { X } from '@my/other-library' when X comes from other library than I'm currently analyzing. For example I would expect the following report:

import { X } from '@my/other-library';

export interface Y extends X { ... }

(similar as if X would be imported from some node_modules package).

To have just import { X } from '@my/other-library' in the report, do I need any special configuration of API Extractor or it's currently impossible in API Extractor?

Note: I'm using a tsconfig with paths mapping to dist folders of other libraries (like "@my/other-library": ["dist/other-library"]") and I'm running API Extractor for each library on their ready precompiled dist d.ts files.

EDIT: I got an answer in the chat room that my above request is not currently possible in API Extractor. So now I created a standalone Feature Request https://github.com/microsoft/rushstack/issues/3666

Platonn avatar Jul 05 '22 22:07 Platonn