Skip to content

Commit 105cfaf

Browse files
devversionmatsko
authored andcommittedMar 18, 2019
fix(compiler-cli): incorrect metadata bundle for multiple unnamed re-exports (#29360)
Currently if an Angular library has multiple unnamed module re-exports, NGC will generate incorrect metdata if the project is using the flat-module bundle option. e.g. _public-api.ts_ ```ts export * from '@mypkg/secondary1'; export * from '@mypkg/secondary2'; ``` There are clearly two unnamed re-exports in the `public-api.ts` file. NGC right now accidentally overwrites all previous re-exports with the last one. Resulting in the generated metadata only containing a reference to `@mypkg/secondary2`. This is problematic as it is common for primary library entry-points to have multiple re-exports (e.g. Material re-exporting all public symbols; or flex-layout exporting all public symbols from their secondary entry-points). Currently Angular Material works around this issue by manually creating a metadata file that declares the re-exports from all unnamed re-exports. (see: https://github.com/angular/material2/blob/master/tools/package-tools/build-release.ts#L78-L85) This workaround works fine currently, but is no longer easily integrated when building the package output with Bazel. In order to be able to build such libraries with Bazel (Material/flex-layout), we need to make sure that NGC generates the proper flat-module metadata bundle. PR Close #29360
1 parent 2ab194c commit 105cfaf

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed
 

‎packages/compiler-cli/src/metadata/bundler.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ export class MetadataBundler {
180180

181181
// Export all the re-exports from this module
182182
if (module && module.exports) {
183+
let unnamedModuleExportsIdx = 0;
183184
for (const exportDeclaration of module.exports) {
184185
const exportFrom = resolveModule(exportDeclaration.from, moduleName);
185186
// Record all the exports from the module even if we don't use it directly.
@@ -202,7 +203,12 @@ export class MetadataBundler {
202203
// Re-export all the symbols from the module
203204
const exportedSymbols = this.exportAll(exportFrom);
204205
for (const exportedSymbol of exportedSymbols) {
205-
const name = exportedSymbol.name;
206+
// In case the exported symbol does not have a name, we need to give it an unique
207+
// name for the current module. This is necessary because there can be multiple
208+
// unnamed re-exports in a given module.
209+
const name = exportedSymbol.name === '*' ?
210+
`unnamed_reexport_${unnamedModuleExportsIdx++}` :
211+
exportedSymbol.name;
206212
exportSymbol(exportedSymbol, name);
207213
}
208214
}

‎packages/compiler-cli/test/metadata/bundler_spec.ts

+15
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,21 @@ describe('metadata bundler', () => {
422422
expect(result.metadata.origins !['E']).toBeUndefined();
423423
});
424424

425+
it('should be able to bundle a library with multiple unnamed re-exports', () => {
426+
const host = new MockStringBundlerHost('/', {
427+
'public-api.ts': `
428+
export * from '@mypkg/secondary1';
429+
export * from '@mypkg/secondary2';
430+
`,
431+
});
432+
433+
const bundler = new MetadataBundler('/public-api', undefined, host);
434+
const result = bundler.getMetadataBundle();
435+
expect(result.metadata.exports).toEqual([
436+
{from: '@mypkg/secondary1'}, {from: '@mypkg/secondary2'}
437+
]);
438+
});
439+
425440
it('should be able to de-duplicate symbols of re-exported modules', () => {
426441
const host = new MockStringBundlerHost('/', {
427442
'public-api.ts': `

0 commit comments

Comments
 (0)
Please sign in to comment.