Skip to content

Refine reexport test cases - #1947

Merged
lukastaegert merged 2 commits into
masterfrom
external-reexport-refinements
Feb 9, 2018
Merged

Refine reexport test cases#1947
lukastaegert merged 2 commits into
masterfrom
external-reexport-refinements

Conversation

@guybedford

@guybedford guybedford commented Feb 6, 2018

Copy link
Copy Markdown
Contributor

This refines some more cases around reexport boundaries, specifically supporting #1675 case of reexporting an imported external namespace, and also further cases around tracing import { x } export { x } scenarios identically to other re-exports in the boundaries.

It feels like we're finally getting close to complete on these scenarios, although there may still be a few surprises to discover.

Edit: Also fixed #1951

@lukastaegert lukastaegert left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! Hope to get this into the next release!

Comment thread src/Chunk.ts Outdated
if (exportDeclaration) {
// if export binding is itself an import binding then continue tracing
const importDeclaration = module.imports[exportDeclaration.localName];
if (importDeclaration) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: As this introduces a lot of special cases and return statements that break the even abstraction layer of the traceExport function and makes it harder to reason about, I would suggest extracting the body of this if-statement into a separate private method so that the code in traceExport could become e.g.

if (exportDeclaration) {
		const importDeclaration = module.imports[exportDeclaration.localName];
		if (importDeclaration) {
      return this.traceReexportedImport(module, importDeclaration);
    }
    return { name, module };
}

Comment thread src/Chunk.ts Outdated
const importDeclaration = module.imports[exportDeclaration.localName];
if (importDeclaration) {
// add the import binding to the shape
const declaration = module.imports[exportDeclaration.localName];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is basically importDeclaration

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the comment preceding this line does not really seem to describe this line but something that happens further down, which is confusing. Actually once this function is extracted, I think the code is understandable even with fewer comments, and comments do not tend to survive refactorings well anyway.

Comment thread src/finalisers/cjs.ts

const exportsNames = imports && imports.some(specifier => specifier.imported !== 'default' && specifier.imported !== '*') ||
reexports && reexports.some(specifier => specifier.imported === 'default');
reexports && reexports.some(specifier => specifier.imported !== 'default' && specifier.imported !== '*');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, good catch!

@@ -1,5 +1,2 @@
import x from 'x';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess its not perfect that this line is retained but probably unavoidable as we are not counting usages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes exactly, if we could track per-chunk usage then this can change, but until then the import statements are never pruned. These statements are well-merged though so it typically doesn't result in any bloat.

});

dependencies.forEach(({ name, reexports }) => {
dependencies.forEach(({ name, imports, reexports }) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know these two loops have previously been separate but it seems they can easily be combined into one loop which will remove one iteration + remove one if statement + make sure in a hard-coded way no reexport is handled twice.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this separation is to ensure that the star exports come first in the output, which is important to the export ordering as star exports get overridden by reexports get overridden by exact name exports.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see, thanks.

Comment thread src/finalisers/es.ts Outdated
if (imports)
output += '\n';
const starExport = reexports.find(specifier => specifier.reexported === '*');
const nsReexport = reexports.find(specifier => specifier.imported === '*' && specifier.reexported !== '*');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love a longer name here, e.g. nonStarReexport as with the shortened name, you have no chance of knowing what it means further down without reading the declaration.

@lukastaegert lukastaegert left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

Comment thread src/Chunk.ts
}

this.populateImport(variable, tracedExport);
this.traceImport(declaration.module, declaration.name);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I totally overlooked this one. So extraction actually removed a code duplication 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup!

@lukastaegert
lukastaegert merged commit ace48f2 into master Feb 9, 2018
@lukastaegert
lukastaegert deleted the external-reexport-refinements branch February 9, 2018 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Named Imports Incorrectly removed if import * is also used

2 participants