* A method can returns a component ID from the component definition using a variant of DJB2 hash * algorithm.
(componentDef: ComponentDef<T>)
| 683 | * algorithm. |
| 684 | */ |
| 685 | function getComponentId<T>(componentDef: ComponentDef<T>): string { |
| 686 | let hash = 0; |
| 687 | |
| 688 | // For components with i18n in templates, the `consts` array is generated by the compiler |
| 689 | // as a function. If client and server bundles were produced with different minification |
| 690 | // configurations, the serializable contents of the function body would be different on |
| 691 | // the client and on the server. This might result in different ids generated. To avoid this |
| 692 | // issue, we do not take the `consts` contents into account if it's a function. |
| 693 | // See https://github.com/angular/angular/issues/58713. |
| 694 | const componentDefConsts = typeof componentDef.consts === 'function' ? '' : componentDef.consts; |
| 695 | |
| 696 | // We cannot rely solely on the component selector as the same selector can be used in different |
| 697 | // modules. |
| 698 | // |
| 699 | // `componentDef.style` is not used, due to it causing inconsistencies. Ex: when server |
| 700 | // component styles has no sourcemaps and browsers do. |
| 701 | // |
| 702 | // Example: |
| 703 | // https://github.com/angular/components/blob/d9f82c8f95309e77a6d82fd574c65871e91354c2/src/material/core/option/option.ts#L248 |
| 704 | // https://github.com/angular/components/blob/285f46dc2b4c5b127d356cb7c4714b221f03ce50/src/material/legacy-core/option/option.ts#L32 |
| 705 | const hashSelectors = [ |
| 706 | componentDef.selectors, |
| 707 | componentDef.ngContentSelectors, |
| 708 | componentDef.hostVars, |
| 709 | componentDef.hostAttrs, |
| 710 | componentDefConsts, |
| 711 | componentDef.vars, |
| 712 | componentDef.decls, |
| 713 | componentDef.encapsulation, |
| 714 | componentDef.standalone, |
| 715 | componentDef.signals, |
| 716 | componentDef.exportAs, |
| 717 | JSON.stringify(componentDef.inputs), |
| 718 | JSON.stringify(componentDef.outputs), |
| 719 | // We cannot use 'componentDef.type.name' as the name of the symbol will change and will not |
| 720 | // match in the server and browser bundles. |
| 721 | Object.getOwnPropertyNames(componentDef.type.prototype), |
| 722 | !!componentDef.contentQueries, |
| 723 | !!componentDef.viewQuery, |
| 724 | ]; |
| 725 | |
| 726 | if (typeof ngDevMode === 'undefined' || ngDevMode) { |
| 727 | // If client and server bundles were produced with different minification configurations, |
| 728 | // the serializable contents of the function body would be different on the client and on |
| 729 | // the server. Ensure that we do not accidentally use functions in component id computation. |
| 730 | for (const item of hashSelectors) { |
| 731 | assertNotEqual( |
| 732 | typeof item, |
| 733 | 'function', |
| 734 | 'Internal error: attempting to use a function in component id computation logic.', |
| 735 | ); |
| 736 | } |
| 737 | } |
| 738 | |
| 739 | for (const char of hashSelectors.join('|')) { |
| 740 | hash = (Math.imul(31, hash) + char.charCodeAt(0)) << 0; |
| 741 | } |
| 742 |
no test coverage detected
searching dependent graphs…