diff --git a/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts b/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts index c32a288ca3..a9487be803 100644 --- a/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts +++ b/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts @@ -56,14 +56,25 @@ export class FactoryGenerator implements ShimGenerator { // Grab the symbol name. .map(decl => decl.name !.text); - let sourceText = ''; + + // If there is a top-level comment in the original file, copy it over at the top of the + // generated factory file. This is important for preserving any load-bearing jsdoc comments. + let comment: string = ''; + if (original.statements.length > 0) { + const firstStatement = original.statements[0]; + if (firstStatement.getLeadingTriviaWidth() > 0) { + comment = firstStatement.getFullText().substr(0, firstStatement.getLeadingTriviaWidth()); + } + } + + let sourceText = comment; if (symbolNames.length > 0) { // For each symbol name, generate a constant export of the corresponding NgFactory. // This will encompass a lot of symbols which don't need factories, but that's okay // because it won't miss any that do. const varLines = symbolNames.map( name => `export const ${name}NgFactory = new i0.ɵNgModuleFactory(${name});`); - sourceText = [ + sourceText += [ // This might be incorrect if the current package being compiled is Angular core, but it's // okay to leave in at type checking time. TypeScript can handle this reference via its path // mapping, but downstream bundlers can't. If the current package is core itself, this will diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index a54f684084..a19e1c6a3e 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -1694,6 +1694,22 @@ describe('ngtsc behavioral tests', () => { expect(emptyFactory).toContain(`export var ɵNonEmptyModule = true;`); }); + it('should copy a top-level comment into a factory stub', () => { + env.tsconfig({'allowEmptyCodegenFiles': true}); + + env.write('test.ts', `/** I am a top-level comment. */ + import {NgModule} from '@angular/core'; + + @NgModule({}) + export class TestModule {} + `); + + env.driveMain(); + + const factoryContents = env.getContents('test.ngfactory.js'); + expect(factoryContents).toMatch(/^\/\*\* I am a top-level comment\. \*\//); + }); + it('should be able to compile an app using the factory shim', () => { env.tsconfig({'allowEmptyCodegenFiles': true});