diff --git a/docs/design/analytics.md b/docs/design/analytics.md index dca7e0039c..5ec9c56adf 100644 --- a/docs/design/analytics.md +++ b/docs/design/analytics.md @@ -69,7 +69,7 @@ Note: There's a limit of 20 custom dimensions. | Id | Flag | Type | |:---:|:---|:---| -| 1 | `UNUSED_1` | `none` | +| 1 | `NgComponentCount` | `number` | | 2 | `UNUSED_2` | `none` | | 3 | `UNUSED_3` | `none` | | 4 | `UNUSED_4` | `none` | diff --git a/etc/api/angular_devkit/core/src/_golden-api.d.ts b/etc/api/angular_devkit/core/src/_golden-api.d.ts index cc667472dc..bd578e135b 100644 --- a/etc/api/angular_devkit/core/src/_golden-api.d.ts +++ b/etc/api/angular_devkit/core/src/_golden-api.d.ts @@ -626,7 +626,7 @@ export declare const NgCliAnalyticsDimensionsFlagInfo: { }; export declare enum NgCliAnalyticsMetrics { - UNUSED_1 = 1, + NgComponentCount = 1, UNUSED_2 = 2, UNUSED_3 = 3, UNUSED_4 = 4, diff --git a/packages/angular_devkit/build_angular/plugins/webpack/analytics.ts b/packages/angular_devkit/build_angular/plugins/webpack/analytics.ts index d2f1ee59d0..147557f8da 100644 --- a/packages/angular_devkit/build_angular/plugins/webpack/analytics.ts +++ b/packages/angular_devkit/build_angular/plugins/webpack/analytics.ts @@ -72,6 +72,7 @@ export function countOccurrences(source: string, match: string, wordBreak = fals class AnalyticsBuildStats { public errors: string[] = []; public numberOfNgOnInit = 0; + public numberOfComponents = 0; public initialChunkSize = 0; public totalChunkCount = 0; public totalChunkSize = 0; @@ -107,6 +108,7 @@ export class NgBuildAnalyticsPlugin { const metrics: (string | number)[] = []; metrics[analytics.NgCliAnalyticsMetrics.BuildTime] = (endTime - startTime); metrics[analytics.NgCliAnalyticsMetrics.NgOnInitCount] = this._stats.numberOfNgOnInit; + metrics[analytics.NgCliAnalyticsMetrics.NgComponentCount] = this._stats.numberOfComponents; metrics[analytics.NgCliAnalyticsMetrics.InitialChunkSize] = this._stats.initialChunkSize; metrics[analytics.NgCliAnalyticsMetrics.TotalChunkCount] = this._stats.totalChunkCount; metrics[analytics.NgCliAnalyticsMetrics.TotalChunkSize] = this._stats.totalChunkSize; @@ -141,10 +143,29 @@ export class NgBuildAnalyticsPlugin { protected _checkTsNormalModule(module: NormalModule) { if (module._source) { + // PLEASE REMEMBER: // We're dealing with ES5 _or_ ES2015 JavaScript at this point (we don't know for sure). + // Just count the ngOnInit occurences. Comments/Strings/calls occurences should be sparse // so we just consider them within the margin of error. We do break on word break though. this._stats.numberOfNgOnInit += countOccurrences(module._source.source(), 'ngOnInit', true); + + // Count the number of `Component({` strings (case sensitive), which happens in __decorate(). + // This does not include View Engine AOT compilation, we use the ngfactory for it. + this._stats.numberOfComponents += countOccurrences(module._source.source(), ' Component({'); + // For Ivy we just count ngComponentDef. + this._stats.numberOfComponents += countOccurrences(module._source.source(), 'ngComponentDef', true); + } + } + + protected _checkNgFactoryNormalModule(module: NormalModule) { + if (module._source) { + // PLEASE REMEMBER: + // We're dealing with ES5 _or_ ES2015 JavaScript at this point (we don't know for sure). + + // Count the number of `.ɵccf(` strings (case sensitive). They're calls to components + // factories. + this._stats.numberOfComponents += countOccurrences(module._source.source(), '.ɵccf('); } } @@ -231,8 +252,10 @@ export class NgBuildAnalyticsPlugin { } // Check that it's a source file from the project. - if (module.constructor === NormalModule && module.resource.endsWith('.ts')) { - this._checkTsNormalModule(module as {} as NormalModule); + if (module.resource.endsWith('.ts')) { + this._checkTsNormalModule(module); + } else if (module.resource.endsWith('.ngfactory.js')) { + this._checkNgFactoryNormalModule(module); } } diff --git a/packages/angular_devkit/core/src/analytics/index.ts b/packages/angular_devkit/core/src/analytics/index.ts index e84d8f5979..962c451ace 100644 --- a/packages/angular_devkit/core/src/analytics/index.ts +++ b/packages/angular_devkit/core/src/analytics/index.ts @@ -30,7 +30,7 @@ export enum NgCliAnalyticsDimensions { } export enum NgCliAnalyticsMetrics { - UNUSED_1 = 1, + NgComponentCount = 1, UNUSED_2 = 2, UNUSED_3 = 3, UNUSED_4 = 4, @@ -62,7 +62,7 @@ export const NgCliAnalyticsDimensionsFlagInfo: { [name: string]: [string, string // This table is used when generating the analytics.md file. It should match the enum above // or the validate-user-analytics script will fail. export const NgCliAnalyticsMetricsFlagInfo: { [name: string]: [string, string] } = { - UNUSED_1: ['UNUSED_1', 'none'], + NgComponentCount: ['NgComponentCount', 'number'], UNUSED_2: ['UNUSED_2', 'none'], UNUSED_3: ['UNUSED_3', 'none'], UNUSED_4: ['UNUSED_4', 'none'],