@@ -10,7 +10,7 @@ import {
1010 AnimationTriggerNames ,
1111 BoundTarget ,
1212 compileClassDebugInfo ,
13- compileClassHmrInitializer ,
13+ compileHmrInitializer ,
1414 compileComponentClassMetadata ,
1515 compileComponentDeclareClassMetadata ,
1616 compileComponentFromMetadata ,
@@ -180,7 +180,7 @@ import {
180180} from './util' ;
181181import { getTemplateDiagnostics } from '../../../typecheck' ;
182182import { JitDeclarationRegistry } from '../../common/src/jit_declaration_registry' ;
183- import { extractHmrInitializerMeta } from './hmr' ;
183+ import { extractHmrMetatadata , getHmrUpdateDeclaration } from '../../. ./hmr' ;
184184
185185const EMPTY_ARRAY : any [ ] = [ ] ;
186186
@@ -267,6 +267,11 @@ export class ComponentDecoratorHandler
267267 enableLetSyntax : this . enableLetSyntax ,
268268 preserveSignificantWhitespace : this . i18nPreserveSignificantWhitespace ,
269269 } ;
270+
271+ // Dependencies can't be deferred during HMR, because the HMR update module can't have
272+ // dynamic imports and its dependencies need to be passed in directly. If dependencies
273+ // are deferred, their imports will be deleted so we won't may lose the reference to them.
274+ this . canDeferDeps = ! enableHmr ;
270275 }
271276
272277 private literalCache = new Map < Decorator , ts . ObjectLiteralExpression > ( ) ;
@@ -280,6 +285,9 @@ export class ComponentDecoratorHandler
280285 private preanalyzeTemplateCache = new Map < DeclarationNode , ParsedTemplateWithSource > ( ) ;
281286 private preanalyzeStylesCache = new Map < DeclarationNode , string [ ] | null > ( ) ;
282287
288+ /** Whether generated code for a component can defer its dependencies. */
289+ private readonly canDeferDeps : boolean ;
290+
283291 private extractTemplateOptions : {
284292 enableI18nLegacyMessageIdFormat : boolean ;
285293 i18nNormalizeLineEndingsInICUs : boolean ;
@@ -876,9 +884,6 @@ export class ComponentDecoratorHandler
876884 this . rootDirs ,
877885 /* forbidOrphanRenderering */ this . forbidOrphanRendering ,
878886 ) ,
879- hmrInitializerMeta : this . enableHmr
880- ? extractHmrInitializerMeta ( node , this . reflector , this . compilerHost , this . rootDirs )
881- : null ,
882887 template,
883888 providersRequiringFactory,
884889 viewProvidersRequiringFactory,
@@ -1600,15 +1605,19 @@ export class ComponentDecoratorHandler
16001605 return [ ] ;
16011606 }
16021607
1603- const perComponentDeferredDeps = this . resolveAllDeferredDependencies ( resolution ) ;
1608+ const perComponentDeferredDeps = this . canDeferDeps
1609+ ? this . resolveAllDeferredDependencies ( resolution )
1610+ : null ;
16041611 const meta : R3ComponentMetadata < R3TemplateDependency > = {
16051612 ...analysis . meta ,
16061613 ...resolution ,
16071614 defer : this . compileDeferBlocks ( resolution ) ,
16081615 } ;
16091616 const fac = compileNgFactoryDefField ( toFactoryMetadata ( meta , FactoryTarget . Component ) ) ;
16101617
1611- removeDeferrableTypesFromComponentDecorator ( analysis , perComponentDeferredDeps ) ;
1618+ if ( perComponentDeferredDeps !== null ) {
1619+ removeDeferrableTypesFromComponentDecorator ( analysis , perComponentDeferredDeps ) ;
1620+ }
16121621
16131622 const def = compileComponentFromMetadata ( meta , pool , makeBindingParser ( ) ) ;
16141623 const inputTransformFields = compileInputTransformFields ( analysis . inputs ) ;
@@ -1620,11 +1629,22 @@ export class ComponentDecoratorHandler
16201629 analysis . classDebugInfo !== null
16211630 ? compileClassDebugInfo ( analysis . classDebugInfo ) . toStmt ( )
16221631 : null ;
1623- const hmrInitializer =
1624- analysis . hmrInitializerMeta !== null
1625- ? compileClassHmrInitializer ( analysis . hmrInitializerMeta ) . toStmt ( )
1626- : null ;
1627- const deferrableImports = this . deferredSymbolTracker . getDeferrableImportDecls ( ) ;
1632+ const hmrMeta = this . enableHmr
1633+ ? extractHmrMetatadata (
1634+ node ,
1635+ this . reflector ,
1636+ this . compilerHost ,
1637+ this . rootDirs ,
1638+ def ,
1639+ fac ,
1640+ classMetadata ,
1641+ debugInfo ,
1642+ )
1643+ : null ;
1644+ const hmrInitializer = hmrMeta ? compileHmrInitializer ( hmrMeta ) . toStmt ( ) : null ;
1645+ const deferrableImports = this . canDeferDeps
1646+ ? this . deferredSymbolTracker . getDeferrableImportDecls ( )
1647+ : null ;
16281648 return compileResults (
16291649 fac ,
16301650 def ,
@@ -1655,7 +1675,9 @@ export class ComponentDecoratorHandler
16551675 : null ,
16561676 } ;
16571677
1658- const perComponentDeferredDeps = this . resolveAllDeferredDependencies ( resolution ) ;
1678+ const perComponentDeferredDeps = this . canDeferDeps
1679+ ? this . resolveAllDeferredDependencies ( resolution )
1680+ : null ;
16591681 const meta : R3ComponentMetadata < R3TemplateDependencyMetadata > = {
16601682 ...analysis . meta ,
16611683 ...resolution ,
@@ -1671,8 +1693,32 @@ export class ComponentDecoratorHandler
16711693 perComponentDeferredDeps ,
16721694 ) . toStmt ( )
16731695 : null ;
1674- const deferrableImports = this . deferredSymbolTracker . getDeferrableImportDecls ( ) ;
1675- return compileResults ( fac , def , classMetadata , 'ɵcmp' , inputTransformFields , deferrableImports ) ;
1696+ const hmrMeta = this . enableHmr
1697+ ? extractHmrMetatadata (
1698+ node ,
1699+ this . reflector ,
1700+ this . compilerHost ,
1701+ this . rootDirs ,
1702+ def ,
1703+ fac ,
1704+ classMetadata ,
1705+ null ,
1706+ )
1707+ : null ;
1708+ const hmrInitializer = hmrMeta ? compileHmrInitializer ( hmrMeta ) . toStmt ( ) : null ;
1709+ const deferrableImports = this . canDeferDeps
1710+ ? this . deferredSymbolTracker . getDeferrableImportDecls ( )
1711+ : null ;
1712+ return compileResults (
1713+ fac ,
1714+ def ,
1715+ classMetadata ,
1716+ 'ɵcmp' ,
1717+ inputTransformFields ,
1718+ deferrableImports ,
1719+ null ,
1720+ hmrInitializer ,
1721+ ) ;
16761722 }
16771723
16781724 compileLocal (
@@ -1684,16 +1730,16 @@ export class ComponentDecoratorHandler
16841730 // In the local compilation mode we can only rely on the information available
16851731 // within the `@Component.deferredImports` array, because in this mode compiler
16861732 // doesn't have information on which dependencies belong to which defer blocks.
1687- const deferrableTypes = analysis . explicitlyDeferredTypes ;
1733+ const deferrableTypes = this . canDeferDeps ? analysis . explicitlyDeferredTypes : null ;
16881734
16891735 const meta = {
16901736 ...analysis . meta ,
16911737 ...resolution ,
16921738 defer : this . compileDeferBlocks ( resolution ) ,
16931739 } as R3ComponentMetadata < R3TemplateDependency > ;
16941740
1695- if ( analysis . explicitlyDeferredTypes !== null ) {
1696- removeDeferrableTypesFromComponentDecorator ( analysis , analysis . explicitlyDeferredTypes ) ;
1741+ if ( deferrableTypes !== null ) {
1742+ removeDeferrableTypesFromComponentDecorator ( analysis , deferrableTypes ) ;
16971743 }
16981744
16991745 const fac = compileNgFactoryDefField ( toFactoryMetadata ( meta , FactoryTarget . Component ) ) ;
@@ -1707,11 +1753,22 @@ export class ComponentDecoratorHandler
17071753 analysis . classDebugInfo !== null
17081754 ? compileClassDebugInfo ( analysis . classDebugInfo ) . toStmt ( )
17091755 : null ;
1710- const hmrInitializer =
1711- analysis . hmrInitializerMeta !== null
1712- ? compileClassHmrInitializer ( analysis . hmrInitializerMeta ) . toStmt ( )
1713- : null ;
1714- const deferrableImports = this . deferredSymbolTracker . getDeferrableImportDecls ( ) ;
1756+ const hmrMeta = this . enableHmr
1757+ ? extractHmrMetatadata (
1758+ node ,
1759+ this . reflector ,
1760+ this . compilerHost ,
1761+ this . rootDirs ,
1762+ def ,
1763+ fac ,
1764+ classMetadata ,
1765+ debugInfo ,
1766+ )
1767+ : null ;
1768+ const hmrInitializer = hmrMeta ? compileHmrInitializer ( hmrMeta ) . toStmt ( ) : null ;
1769+ const deferrableImports = this . canDeferDeps
1770+ ? this . deferredSymbolTracker . getDeferrableImportDecls ( )
1771+ : null ;
17151772 return compileResults (
17161773 fac ,
17171774 def ,
@@ -1724,6 +1781,50 @@ export class ComponentDecoratorHandler
17241781 ) ;
17251782 }
17261783
1784+ compileHmrUpdateDeclaration (
1785+ node : ClassDeclaration ,
1786+ analysis : Readonly < ComponentAnalysisData > ,
1787+ resolution : Readonly < ComponentResolutionData > ,
1788+ ) : ts . FunctionDeclaration | null {
1789+ if ( analysis . template . errors !== null && analysis . template . errors . length > 0 ) {
1790+ return null ;
1791+ }
1792+
1793+ // Create a brand-new constant pool since there shouldn't be any constant sharing.
1794+ const pool = new ConstantPool ( ) ;
1795+ const meta : R3ComponentMetadata < R3TemplateDependency > = {
1796+ ...analysis . meta ,
1797+ ...resolution ,
1798+ defer : this . compileDeferBlocks ( resolution ) ,
1799+ } ;
1800+ const fac = compileNgFactoryDefField ( toFactoryMetadata ( meta , FactoryTarget . Component ) ) ;
1801+ const def = compileComponentFromMetadata ( meta , pool , makeBindingParser ( ) ) ;
1802+ const classMetadata =
1803+ analysis . classMetadata !== null
1804+ ? compileComponentClassMetadata ( analysis . classMetadata , null ) . toStmt ( )
1805+ : null ;
1806+ const debugInfo =
1807+ analysis . classDebugInfo !== null
1808+ ? compileClassDebugInfo ( analysis . classDebugInfo ) . toStmt ( )
1809+ : null ;
1810+ const hmrMeta = this . enableHmr
1811+ ? extractHmrMetatadata (
1812+ node ,
1813+ this . reflector ,
1814+ this . compilerHost ,
1815+ this . rootDirs ,
1816+ def ,
1817+ fac ,
1818+ classMetadata ,
1819+ debugInfo ,
1820+ )
1821+ : null ;
1822+ const res = compileResults ( fac , def , classMetadata , 'ɵcmp' , null , null , debugInfo , null ) ;
1823+ return hmrMeta === null || res . length === 0
1824+ ? null
1825+ : getHmrUpdateDeclaration ( res , pool . statements , hmrMeta , node . getSourceFile ( ) ) ;
1826+ }
1827+
17271828 /**
17281829 * Locates defer blocks in case scope information is not available.
17291830 * For example, this happens in the local compilation mode.
0 commit comments