Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[api-extractor] Support "import * as __ from __" for local paths #1029

Closed
octogonz opened this issue Jan 16, 2019 · 73 comments · Fixed by grafana/grafana#21931 or #1796
Closed

[api-extractor] Support "import * as __ from __" for local paths #1029

octogonz opened this issue Jan 16, 2019 · 73 comments · Fixed by grafana/grafana#21931 or #1796

Comments

@octogonz
Copy link
Collaborator

@octogonz octogonz commented Jan 16, 2019

PR #1002 adds support for declarations like this:

import * as React from 'react';

This is a trivial implementation, where we pretend that * is an actual name exported by the "react" package. It does not work for the general form that introduces a new namespace, for example:

// For example, "Button" in controls.ts becomes "controls.Button"
import * as controls from './controls';

This form is called ts.SyntaxKind.NamespaceImport because it is essentially a more general form of the namespace controls { } declaration kind.

As such, it should probably produce an ApiItemKind.Namespace item.

@octogonz
Copy link
Collaborator Author

@octogonz octogonz commented Jan 17, 2019

@gf3 shared a branch gf3/api-extractor-issue@30de59d that repros this issue.

@octogonz
Copy link
Collaborator Author

@octogonz octogonz commented Jan 17, 2019

Some other examples were given in the comments for issue #663

@shlomiassaf
Copy link

@shlomiassaf shlomiassaf commented Jan 21, 2019

@pgonzal I think that those imports should be handled differently, from a usage perspective and rather then semantic...

import * as React from 'react';
import * as controls from './controls';

export class ABC {
  p1: React.Component;
  p2: controls.Control;
}

The code above is similar to this:

import { Component }  from 'react';
import { Control } from './controls';

export class ABC {
  p1: Component;
  p2: Control;
}

The local import is purely semantic...
When generating docs it doesn't make sense to render p2: controls.Control; so the library should find the direct reference and ignore the namespace.

When importing from third party, it's a different story and the way it is rendered is up to the user, just need to make sure there's enough info...

@octogonz
Copy link
Collaborator Author

@octogonz octogonz commented Jan 27, 2019

@shlomiassaf

FYI API Extractor wants all reachable types to have exported names, mainly for the software engineering reason that it's more difficult to use an API with anonymous types, and also more difficult for the documentation to talk about it.

For your second example, API Extractor should warn about Component, something like this:

import { Component }  from 'react';
import { Control } from './controls';

export class ABC {
  // WARNING: the declaration "Component" is not exported
  p1: Component;
  p2: Control;
}

Whereas in your first example, it should issue this sort of warning:

import * as React from 'react';
import * as controls from './controls';

export class ABC {
  // (no warning because the "React" module is an external package)
  p1: React.Component;

  // WARNING: the declaration "controls" is not exported
  p2: controls.Control;
}

If you mixed them, then the desired behavior is less clear:

import * as React from 'react';
import * as controls from './controls';
export { Control } from './controls';

export class ABC {
  // (no warning because the "React" module is an external package)
  p1: React.Component;

  // WARNING: the declaration "controls" is not exported
  p2: controls.Control;
}

I suppose the ideal behavior might be to realize that controls.Control is a synonym for Control and normalize it to eliminate the controls. part. But this is technically difficult. I haven't thought about it in depth because this problem seems to never occur in any of our code bases heheh.

@shlomiassaf
Copy link

@shlomiassaf shlomiassaf commented Jan 31, 2019

@octogonz Thanks for clear explanation.

I think that the underlaying issue is more about the concept and direction of this project.
This tool is used for several tasks, document generation is one of them.

We can agree that generating documentation from the json output can happen is a lot of ways, so many that I can't count :)

At it's current state, the project does provide a way to change the behaviour, configuring it, etc...

Taking a lot of assumptions is risky because it means that it will only do and support things that occur in your code bases and that's not a very good approach for a public project.

I see great importance in tsdoc and this tool and I think that wide adoption will help the community because there are a lot of tools for this job, each with pros/cons and having a unified tool from MS is probably the best solution.

But, for that we need flexibility, understanding that your code base might not be the same as another's code base.

For example, let's say I built an angular library that uses a lot of symbols from various @angular libraries and also symbols from rxjs

Now of course all of them are not exported, but in my doc generator I can decide to generate links for them, based on some schema... links to the external documentation for these libraries...

So if a new ApiItem is created hosting the (not) exported symbol with it's package name, the doc generator can do the magic...

In angular it's a very simple schema: https://angular.io/api/[PACKAGE NAME]/[SYMBOL NAME]
Examples:

import { HttpHeaders } from '@angular/common/http';

https://angular.io/api/common/http/HttpHeaders

import { Component } from '@angular/core';

https://angular.io/api/core/Component

Usually, since documentation is auto-generated, a schema always exists...

alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 7, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 11, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 13, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611
mhevery added a commit to angular/angular that referenced this issue Feb 14, 2019
This enabled dts flattening in the final distrubutable package.

Notes:
 - For the time being this is an opt-in feature via the `ng_module` attribute  `bundle_dts`, however in the near future this will be turned on by default.
 - This only supports the legacy compiler `ngc`, as `ngtsc` emits namespaced imports `import * as __` from local modules which is not supported for the time being by API Extractor. See: microsoft/rushstack#1029

Ref: TOOL-611

PR Close #28588
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 21, 2019
At the moment, the API extractor doesn't support local namespaced imports, this will break the generation of flat dts files. When we turn on dts bundling for this package it will break. Hence this is the ground work needed for making this package compatable with the API extractor.

See: microsoft/rushstack#1029

Relates to angular#28588
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Feb 21, 2019
At the moment, the API extractor doesn't support local namespaced imports, this will break the generation of flat dts files. When we turn on dts bundling for this package it will break. Hence this is the ground work needed for making this package compatable with the API extractor.

See: microsoft/rushstack#1029

Relates to angular#28588
IgorMinar added a commit to angular/angular that referenced this issue Feb 22, 2019
At the moment, the API extractor doesn't support local namespaced imports, this will break the generation of flat dts files. When we turn on dts bundling for this package it will break. Hence this is the ground work needed for making this package compatable with the API extractor.

See: microsoft/rushstack#1029

Relates to #28588

PR Close #28642
gkalpak added a commit to gkalpak/angular that referenced this issue Feb 22, 2019
At the moment, the API extractor doesn't support local namespaced imports, this will break the generation of flat dts files. When we turn on dts bundling for this package it will break. Hence this is the ground work needed for making this package compatable with the API extractor.

See: microsoft/rushstack#1029

Relates to angular#28588

PR Close angular#28642
rudolf added a commit to rudolf/kibana that referenced this issue Mar 21, 2019
Becasue of microsoft/rushstack#1029
api-extractor can't use core/index.ts as a single entry point for
analyzing the public and server API's as isolated namespaces.

Instead we analyze these projects separately. This introduces other
problems like the api review files and documentation always being
called "kibana." from the package.json filename.
@jeremymeng
Copy link
Member

@jeremymeng jeremymeng commented Apr 1, 2019

We are currently using the following pattern. Is there a recommended workaround?

import * as Models from "../lib/generated/lib/models";
...
export { Models };

@hiranya911
Copy link
Contributor

@hiranya911 hiranya911 commented Aug 29, 2020

Is this issue also going to address problems like #2145 where API Extractor does not include re-exported namespace content in the API report? Fixes in 7.8.2-pr1796.0 allows me to generate a report, but it doesn't include any of the re-exported APIs.

@jasonswearingen
Copy link
Contributor

@jasonswearingen jasonswearingen commented Sep 14, 2020

7.8.2-pr1796.0 kind of works, but I have to disable apiReport

@jasonswearingen
Copy link
Contributor

@jasonswearingen jasonswearingen commented Sep 21, 2020

there is another, similar problem with export * as moduleName from "./moduleName" which gives the generic error message:

Internal Error: Unable to parse module specifier

the 7.8.2-pr1796.0 does not work with the export * style

@hiranya911
Copy link
Contributor

@hiranya911 hiranya911 commented Nov 25, 2020

Just ran into this while trying to re-export types declared in another module:

import * as _app from './app/index';

export namespace credential {
  export type Credential = _app.Credential;
}

It seems, at least for cases like the above you can workaround the error by doing something like this:

import { Credential as _Credential } from './app/index';

export namespace credential {
  export type Credential = _Credential;
}

@IgorMinar
Copy link

@IgorMinar IgorMinar commented Jun 7, 2021

@octogonz thanks for looking into this problem. It seems that #1796 is a solution that is already in a pretty good shape. Could you please help us get it across the line and resolve this problem?

Fixing this issue would significantly help Angular (angular/angular#42064) where we heavily use namespaces to reduce the size (and associated memory footprint) of generated d.ts files.

@gregjacobs
Copy link

@gregjacobs gregjacobs commented Jun 22, 2021

@IgorMinar @octogonz +1 for this - we just upgraded to Angular 12 and can no longer use API extractor 😢

@octogonz
Copy link
Collaborator Author

@octogonz octogonz commented Jun 30, 2021

Also, please support export * as util from './utils' syntax

This syntax is not handled by PR #1796. It is a relatively easy addition, but in the interest of getting that PR finally merged, I'm going to postpone export * as to later PR. I've created #2780 to track that.

@octogonz
Copy link
Collaborator Author

@octogonz octogonz commented Jun 30, 2021

PR #1796 was released with API Extractor 7.17.0

@IgorMinar @gregjacobs Could you try it with Angular 12 and confirm whether that issue is resolved? If not, please create a new GitHub issue with repro steps for Angular. Thanks!

@IgorMinar
Copy link

@IgorMinar IgorMinar commented Jul 1, 2021

We will. Thank you!

alan-agius4 added a commit to alan-agius4/angular that referenced this issue Jul 1, 2021
This change adds support for namespaced imports from local paths which is needed to support Ivy output.

See: microsoft/rushstack#1029
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Jul 1, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Jul 1, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Jul 1, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Jul 1, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.
@alan-agius4
Copy link
Contributor

@alan-agius4 alan-agius4 commented Jul 1, 2021

Hi @octogonz, can confirm that 7.17.0 addresses the issue with Angular.

alan-agius4 added a commit to alan-agius4/angular that referenced this issue Jul 2, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.
alan-agius4 added a commit to alan-agius4/angular that referenced this issue Jul 2, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.
atscott added a commit to angular/angular that referenced this issue Jul 2, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.

PR Close #42728
atscott added a commit to angular/angular that referenced this issue Jul 2, 2021
It is now possible to bundle DTS files of Ivy libraries since the blocker microsoft/rushstack#1029 has been addressed upstream.

PR Close #42728
@octogonz
Copy link
Collaborator Author

@octogonz octogonz commented Jul 6, 2021

Hi @octogonz, can confirm that 7.17.0 addresses the issue with Angular.

Awesome! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment