fix #190: ensure re-exported default aliases aren't renamed

This commit is contained in:
Evan Wallace
2020-06-20 10:35:52 -07:00
parent 0be23dec5c
commit 21244e7000
3 changed files with 75 additions and 3 deletions

View File

@@ -1,5 +1,11 @@
# Changelog
## Unreleased
* Fix re-export statements ([#190](https://github.com/evanw/esbuild/issues/190))
The previous release caused a regression due to some behind-the-scenes work for the upcoming code splitting feature. The re-export alias in statements of the form `export { foo as bar } from 'path'` could sometimes incorrectly be renamed to something else, such as `foo` becoming `foo2`. This release fixes the bug.
## 0.5.5
* Implement logical assignment operator transforms

View File

@@ -5310,3 +5310,66 @@ export {
},
})
}
func TestReExportDefault(t *testing.T) {
expectBundled(t, bundled{
files: map[string]string{
"/entry.js": `
export {default as foo} from './foo'
export {default as bar} from './bar'
`,
"/foo.js": `
export default 'foo'
`,
"/bar.js": `
export default 'bar'
`,
},
entryPaths: []string{"/entry.js"},
parseOptions: parser.ParseOptions{
IsBundling: true,
},
bundleOptions: BundleOptions{
IsBundling: true,
AbsOutputFile: "/out.js",
},
expected: map[string]string{
"/out.js": `// /foo.js
const foo_default = "foo";
// /bar.js
const bar_default = "bar";
// /entry.js
export {
bar_default as bar,
foo_default as foo
};
`,
},
})
}
func TestReExportDefaultNoBundle(t *testing.T) {
expectBundled(t, bundled{
files: map[string]string{
"/entry.js": `
export {default as foo} from './foo'
export {default as bar} from './bar'
`,
},
entryPaths: []string{"/entry.js"},
parseOptions: parser.ParseOptions{
IsBundling: false,
},
bundleOptions: BundleOptions{
IsBundling: false,
AbsOutputFile: "/out.js",
},
expected: map[string]string{
"/out.js": `export {default as foo} from "./foo";
export {default as bar} from "./bar";
`,
},
})
}

View File

@@ -6965,7 +6965,7 @@ func (p *parser) visitAndAppendStmt(stmts []ast.Stmt, stmt ast.Stmt) []ast.Stmt
}
case *ast.SExportClause:
// "export {foo}
// "export {foo}"
for i, item := range s.Items {
name := p.loadNameFromRef(item.Name.Ref)
ref := p.findSymbol(name).ref
@@ -6980,10 +6980,13 @@ func (p *parser) visitAndAppendStmt(stmts []ast.Stmt, stmt ast.Stmt) []ast.Stmt
p.currentScope.Generated = append(p.currentScope.Generated, s.NamespaceRef)
p.recordDeclaredSymbol(s.NamespaceRef)
// This is a re-export and the names are symbols in another file
// This is a re-export and the symbols created here are used to reference
// names in another file. This means the symbols are really aliases. The
// symbols are marked as "unbound" so that they aren't accidentally renamed
// by the code that avoids symbol name collisions.
for i, item := range s.Items {
name := p.loadNameFromRef(item.Name.Ref)
ref := p.newSymbol(ast.SymbolOther, name)
ref := p.newSymbol(ast.SymbolUnbound, name)
p.currentScope.Generated = append(p.currentScope.Generated, ref)
p.recordDeclaredSymbol(ref)
s.Items[i].Name.Ref = ref