-
Notifications
You must be signed in to change notification settings - Fork 594
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] Improve symbol analyzer to support "export * from" constructs #1002
Conversation
@natalieethell FYI #Resolved |
FYI: The review file generating will break with export from external package like following: export { SemVer } from 'semver'; The error is: Note that the test case And, in such case that I found this problem when trying to add support for |
And another one, also for the case: export { SemVer } from 'semver'; The generated api.json would include detail type declarations for |
@adventure-yunfei I just pushed an update I was working on that hopefully should address this case. BTW the main idea behind The algorithm in my PR branch is still missing a major case. It should now correctly handle these cases: src/index.ts export * from './SomeFile';
export * from 'other-package'; ...if we have src/SomeFile.ts: export class X { } But it does not yet handle this case: src/index.ts export { X } from './OtherFile'; ...if we have src/OtherFile.ts: export * from 'other-package'; I don't believe there is an easy solution for that. Replacing ts.TypeChecker.getExportsOfModule() was not too difficult, because I'm hoping to get some time over the holiday to finish this. Originally I was going to defer this work until after version 7 was released, but several teams at work are encountering these issues, so they can't use version 7 without this fix. #Resolved |
I've discovered some designs of api-extractor. To solving this kind of "export from external package" problem, my idea is to always analyze them no matter local or external, instead of blocking analyzing for external. api-extractor is treating external symbols too specially and I wonder it may lead to potential risks. For *.d.ts rollup or review file generator, detail external declarations may not be helpful (as they simply output the original Consider the case (for api.json generator): export { ExternalModule } from 'external-package'; For api.json (or related api-documenter output), what it should be? Two choices:
From the api sight, I would prefer the second one. And, for any other generators including those that may be added in future, I would prefer to give all details (declaration details, reexport informations) to the generator and let themselves to choose what the want to generate. e.g.:
When the *.d.ts and review file generators see an external symbol, they generate a reexport statement; When the api.json generator (or any other generator taking case of declaration details instead of reexport info), it generate the declaration details. Just my simple thoughts. I'm learning api-extractor ~ #Resolved |
@adventure-yunfei wrote:
I'm not sure I agree with this. We are encountering this situation in real world scenarios, e.g. office-ui-fabric-react has a number of instances as part of a transitional step to split up a monolithic NPM package into smaller packages. In my view, this sort of thing: export { ExternalModule } from 'external-package'; ...is its own kind of API item that is similar to a TypeScript type alias. The API reference web site will already have a full set documentation for For the *.d.ts rollup, it would be technically incorrect to duplicate the declarations. (For example, the TypeScript compiler will not consider class types to be interchangeable if they contain any private members.) The *.api.ts review file is a somewhat special scenario. Since this is used to detect compatibility breaks, it may be useful to inline the full signature of the external declaration. Issue #896 is essentially asking for this. In the comments for that issue I gave some reasons why it should perhaps be an "opt-in" behavior. In any case, it seems clear that API Extractor's analyzer needs to know which package a declaration comes from, in order to solve these sorts of problems. #Resolved |
Hmm... Here and here I came across some usages of the term "nominal" to mean "type compatibility based on the name of a type, not just its signature". I wonder if API Extractor should choose a different name for our concept. @nickpape-msft @iclanton #Resolved |
[api-extractor] Add unit tests for PR #1002
… * from" constructs
… declarations (i.e. where both CollectorEntity.exported=true and AstSymbol.imported=true)
…ted multiple times (fixes GitHub issue #950)
5b870cc
to
432d977
Compare
Agree with you now. Reexported items from external packages should be handled in user side, not the api-extractor core. It's a special case to merge some packages' contents. #Resolved |
b83f09b
to
29be5e0
Compare
|
||
// tslint:disable-next-line:no-any | ||
return (ts as any).getResolvedModule(sourceFile, moduleNameText); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you split the compiler internals into a separate file so it's clear that's what they are. It'll also be easier to find problems if the compiler internals change. #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (this._shouldIncludeReleaseTag(releaseTag, dtsKind)) { | ||
if (!this._shouldIncludeReleaseTag(releaseTag, dtsKind)) { | ||
indentedWriter.writeLine(); | ||
indentedWriter.writeLine(`/* Excluded from this release type: ${entity.nameForEmit} */`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nameForEmit [](start = 81, length = 11)
Sanetize? #WontFix
* This is true if exportNames contains only one string, and the declaration can be exported using the inline syntax | ||
* such as "export class X { }" instead of "export { X }". | ||
*/ | ||
public get emitWithExportKeyword(): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emitWithExportKeyword [](start = 13, length = 21)
Maybe shouldInlineExport
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fixed now. In reply to: 449750119 [](ancestors = 449750119) |
I renamed it to "nominalAnalysis" In reply to: 451778545 [](ancestors = 451778545) |
fae4865
to
f2e0fd8
Compare
This PR was published as the beta release api-extractor@7.0.10 and api-documenter@7.0.15. To try it, do |
This PR turned into a full rewrite of the symbol analyzer, adding the following capabilities:
Support
export * from './localFile';
by merging those declaration into the entry point as beforeSupport
export * from 'external-package'
by emitting anexport *
in the outputSupport
export { A } from './localFile';
where ./localFile.ts obtainsA
by doingexport * from 'external-package';
Allow a declaration to be exported more than once: