fix(ngcc): do not output duplicate ɵprov properties (#34085)

Previously, the Angular AOT compiler would always add a
`ɵprov` to injectables. But in ngcc this resulted in duplicate `ɵprov`
properties since published libraries already have this property.

Now in ngtsc, trying to add a duplicate `ɵprov` property is an error,
while in ngcc the additional property is silently not added.

// FW-1750

PR Close #34085
This commit is contained in:
Pete Bacon Darwin
2019-11-27 14:17:57 +00:00
committed by Miško Hevery
parent 658087be7e
commit 2fb9b7ff1b
7 changed files with 155 additions and 10 deletions

View File

@ -96,7 +96,7 @@ export class DecorationAnalyzer {
this.isCore, /* annotateForClosureCompiler */ false),
new InjectableDecoratorHandler(
this.reflectionHost, NOOP_DEFAULT_IMPORT_RECORDER, this.isCore,
/* strictCtorDeps */ false),
/* strictCtorDeps */ false, /* errorOnDuplicateProv */ false),
new NgModuleDecoratorHandler(
this.reflectionHost, this.evaluator, this.fullMetaReader, this.fullRegistry,
this.scopeRegistry, this.referencesRegistry, this.isCore, /* routeAnalyzer */ null,

View File

@ -175,6 +175,36 @@ runInEachFileSystem(() => {
expect(jsContents).toMatch(/\bvar _c0 =/);
});
it('should add ɵfac but not duplicate ɵprov properties on injectables', () => {
compileIntoFlatEs5Package('test-package', {
'/index.ts': `
import {Injectable, ɵɵdefineInjectable} from '@angular/core';
export const TestClassToken = 'TestClassToken';
@Injectable({providedIn: 'module'})
export class TestClass {
static ɵprov = ɵɵdefineInjectable({ factory: () => {}, token: TestClassToken, providedIn: "module" });
}
`,
});
const before = fs.readFile(_(`/node_modules/test-package/index.js`));
const originalProp = /ɵprov[^;]+/.exec(before) ![0];
mainNgcc({
basePath: '/node_modules',
targetEntryPointPath: 'test-package',
propertiesToConsider: ['main'],
});
const after = fs.readFile(_(`/node_modules/test-package/index.js`));
expect(before).toContain(originalProp);
expect(countOccurrences(before, 'ɵprov')).toEqual(1);
expect(countOccurrences(before, 'ɵfac')).toEqual(0);
expect(after).toContain(originalProp);
expect(countOccurrences(after, 'ɵprov')).toEqual(1);
expect(countOccurrences(after, 'ɵfac')).toEqual(1);
});
it('should add generic type for ModuleWithProviders and generate exports for private modules',
() => {
compileIntoApf('test-package', {
@ -1231,3 +1261,12 @@ runInEachFileSystem(() => {
}
});
});
function countOccurrences(haystack: string, needle: string): number {
const regex = new RegExp(needle, 'g');
let count = 0;
while (regex.exec(haystack)) {
count++;
}
return count;
}