From 2a03a3da556d6f8fa1bb0c579ac447702f5e7ae9 Mon Sep 17 00:00:00 2001 From: Benjamin Dobler Date: Sun, 22 Mar 2026 17:17:40 +0100 Subject: [PATCH] fix: invalidate Vite module graph on template/style HMR updates Two fixes for HMR reliability: 1. After sending the angular:component-update WS event, call server.moduleGraph.invalidateModule() so that Vite's transform cache is cleared and full page reloads serve fresh content. 2. In handleHotUpdate, skip the full-reload for component .ts files that have a pending HMR update (pendingHmrUpdates). Template/style changes trigger handleHotUpdate for the owning .ts file via Vite's module graph dependency tracking, but the .ts file wasn't actually edited. Without this check, the full-reload overrides the HMR update. --- .DS_Store | Bin 0 -> 6148 bytes crates/.DS_Store | Bin 0 -> 6148 bytes napi/.DS_Store | Bin 0 -> 6148 bytes napi/angular-compiler/vite-plugin/index.ts | 15 +++++++++++++++ 4 files changed, 15 insertions(+) create mode 100644 .DS_Store create mode 100644 crates/.DS_Store create mode 100644 napi/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..eb3b4d48dc134b07662fb5b165c05af35d05efca GIT binary patch literal 6148 zcmeHK&o2W(6#j-qgNTbDNY(*2Ne>c<%aV#8C*co3wW&&L8&$4*6#fbSgoKmCrAG-T zadUH%_y@c(C?P zghH-SKv*iIxAwwvB^K=loB~dPzor1cyWN<@9(Hkr*!$b{(&{gVnM}46W@$W?D_)(i zUey=lF}ZJJD*NU+!RHS=;!!{m$JQA#zc6e1%>3^&2M^QNGJj)kIc(-`=eP1MM4Y$h zGcWd0L)OZU(cyT6$>FBj(4b`5~=9MSLN7k5g)YT4I_^l42|#XB(`GheKjfLDAwc zG<9wI%>2dt`lZg_m}~AzJHM58!sopGlvnNqwo#U?8cMBNj9siee-&%;dRk7u>h~sb zZIkCu;!WO@^*84Iozb1mmg-aJYNvoxz$wsBfX@e?3S*!#QYeoOsye94evgrj+VUr>gG!p3otLOF#heI3gN fU&SL-q><0(24SEvQb;3Y?vH?!!BtLyUsd1(orUve literal 0 HcmV?d00001 diff --git a/crates/.DS_Store b/crates/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..75368568e34121028770c6683ba909cd0c7a7b88 GIT binary patch literal 6148 zcmeHKO-sW-5Pe&FsCX$@&|@xo@7YT%5qk5`A5iUwRcM+JD0s}J7k`Zx#ed+bC;x}P z!8f~Wn~(~vf{4t(>`P|%Wjk*}rUSrq=A$;y1kj)h*7iAUFqs#xSj|Ud(%5HAag7Xp z43Sh;Yv3;`AZK^TQ=4IeIf~~u!wpX{Lu_Y<7*8kd-Y|(%n?`H7+@2XHQ8bt)12P(? zXU`Aar`Pjc*rOk?)7!$YKFYZ*TFmR7?`VHx-Z4_#QHe3KQpSVJ_g%QfoEP22+sTW~ zdF#F7WS#YQ_@%tlN6A}F6;K6Kflmckv&9+*4s}!oQ~_0BrGR`N0=i)6F?VP`9UN>6 zK&&%tjn~pk2q*9uddwYihGra<=%~iG7{<{V5B$2&WA4z=VSMvp{LaRAD8}y2=LdE< zOz2QYRX`OeE3oHon^ONTzV83aB)wAwRDpk`fT>5lsKbfarKrVkmS2U-Jn)jDcL6^{+Q<=_(<5`{+E`hzfXJCk%{?aGQ<9M3pQ`iQJ zi`$oj$EV|;`6a*dD;A9y2lpK64l>}3u8~`bUu1=dlU6Qt^S;im8UNtz@b&b;#lP~* zEdPx8JKI*AMkwWARg?i`KpEH|1E|?7!LFdr%78MU3@jPo?}No)j6BwY?$d$EwE)0A z)K0MGUV?qB$H-$Xh#iO#SD?5W-(nbXhu(U-$YU)i?qq!PVf>qo?@)|;JI=SxoJ=IB zvofFzv>Div$B^s)$@>1k?W9l2fHLr}7%=^K9FLHaudSWrxYk;XGYl5Cs|A-XSh!LQ fTQ0@>7*3$KyZ}ZXYe8rr`bWUgpp!DNQ3gH$>W^ft literal 0 HcmV?d00001 diff --git a/napi/angular-compiler/vite-plugin/index.ts b/napi/angular-compiler/vite-plugin/index.ts index 7fa326167..067345cc0 100644 --- a/napi/angular-compiler/vite-plugin/index.ts +++ b/napi/angular-compiler/vite-plugin/index.ts @@ -370,6 +370,13 @@ export function angular(options: PluginOptions = {}): Plugin[] { event: 'angular:component-update', data: eventData, }) + + // Invalidate Vite's module transform cache so that a full page reload + // picks up the new template/style content instead of serving stale output. + const mod = server.moduleGraph.getModuleById(componentFile) + if (mod) { + server.moduleGraph.invalidateModule(mod) + } } } } @@ -654,6 +661,14 @@ export function angular(options: PluginOptions = {}): Plugin[] { debugHmr('componentIds keys: %O', Array.from(componentIds.keys())) if (isComponent && hasComponentId) { + // If there's a pending HMR update for this component, the .ts module + // was invalidated by our fs.watch handler (template/style change), not + // by an actual .ts file edit. Skip the full reload — HMR handles it. + if (pendingHmrUpdates.has(ctx.file)) { + debugHmr('skipping full reload — pending HMR update from template/style change') + return [] + } + debugHmr('triggering full reload for component file change') // Component FILE changes require a full reload because: // - Class definition changes can't be hot-swapped safely