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

Multiple exports for the same concrete type result in a build error that is inconsistent with TypeScript #568

Closed
wants to merge 2 commits into from

Conversation

ggoodman
Copy link

@ggoodman ggoodman commented Nov 30, 2020

This PR is intended to encode behaviour that I think should be considered valid but which is currently considered invalid in esbuild.

When multiple modules re-export the same underlying type (via different paths) this appears to produce an 'ambiguous import' error:

case importAmbiguous:
source := c.files[tracker.sourceIndex].source
namedImport := c.files[tracker.sourceIndex].repr.(*reprJS).ast.NamedImports[tracker.importRef]
c.addRangeError(source, js_lexer.RangeOfIdentifier(source, namedImport.AliasLoc),
fmt.Sprintf("Ambiguous import %q has multiple matching exports", namedImport.Alias))

I think TypeScript is taking a different approach which is to say that since the 'duplicate' exports refer to the same concrete type, they can be deduplicated instead of being treated as conflicting. In the included test, there is only one Foo class but it gets exported via the entrypoint through two competing paths. Perhaps the linker needs a concept of source identity beyond identifier identity.

@evanw
Copy link
Owner

evanw commented Dec 4, 2020

Sorry, I'm confused. This test case seems to work fine? This is what the CI failure says:

--- FAIL: TestTSDuplicateExportRefs (0.00s)
    --- FAIL: TestTSDuplicateExportRefs/#00 (0.00s)
        bundler_importstar_ts_test.go:505: No snapshot saved for TestTSDuplicateExportRefs
            ---------- /out.js ----------
            // /types1.ts
            var Foo = class {
            };
            
            // /entry.ts
            console.log(Foo);

That means there was no build error and the build successfully generated an output file.

@ggoodman
Copy link
Author

ggoodman commented Dec 4, 2020

Hi @evanw, sorry about that. Missed the correct workflow and have since added the test. Interestingly, with the snapshot, the test passes.

This tells me that I've been unable to reproduce the issue that I was seeing in a much larger codebase where an export * from './catinthehat_crate' was conflicting with a more specific export like export { Thing1, Thing2 } from './catinthehat_crate'.

I've since successfully gotten the offending code 'fixed' in the project on which I was trying to run esbuild so this is less of an issue now.

I leave to your judgement whether the (now passing) test adds value or not.

@evanw
Copy link
Owner

evanw commented Dec 5, 2020

This tells me that I've been unable to reproduce the issue that I was seeing in a much larger codebase where an export * from './catinthehat_crate' was conflicting with a more specific export like export { Thing1, Thing2 } from './catinthehat_crate'.

Thanks for the tip. I'll treat this as an issue report and start investigating. I think I might know what this is about.

@evanw evanw closed this in b196707 Dec 5, 2020
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.

2 participants