@@ -161,6 +161,60 @@ export function fetchLinksFromHtml (
161161 } )
162162}
163163
164+ /**
165+ * Get a MutationObserver that will remove the convertStyle and disabledLink when the the other is removed
166+ * @param convertStyle converted style
167+ * @param disabledLink disabled link
168+ * @returns MutationObserver
169+ */
170+ export function getAutoRemoveObserver ( convertStyle : HTMLStyleElement , disabledLink : HTMLLinkElement ) : MutationObserver {
171+ const observer = new MutationObserver ( ( mutations , obs ) => {
172+ mutations . forEach ( ( mutation ) => {
173+ const removedNodes = mutation . removedNodes
174+ const removedLength = removedNodes . length
175+ let needRemoveElement : Element | null = null
176+ for ( let i = 0 ; i < removedLength ; i ++ ) {
177+ const removedNode = removedNodes [ i ]
178+ if ( removedNode === disabledLink ) {
179+ needRemoveElement = convertStyle
180+ break
181+ }
182+ if ( removedNode === convertStyle ) {
183+ needRemoveElement = disabledLink
184+ break
185+ }
186+ }
187+ if ( needRemoveElement ) {
188+ obs . disconnect ( )
189+ needRemoveElement . remove ( )
190+ }
191+ } )
192+ } )
193+
194+ return observer
195+ }
196+
197+ function getDisabledLink ( convertStyle : HTMLStyleElement , linkInfo : LinkSourceInfo , app : AppInterface ) {
198+ const disabledLink = pureCreateElement ( 'link' )
199+ const appSpaceData = linkInfo . appSpace [ app . name ]
200+ appSpaceData . attrs ?. forEach ( ( value , key ) => {
201+ if ( key === 'href' ) {
202+ globalEnv . rawSetAttribute . call ( disabledLink , 'data-origin-href' , value )
203+ globalEnv . rawSetAttribute . call ( disabledLink , 'href' , CompletionPath ( value , app . url ) )
204+ } else {
205+ globalEnv . rawSetAttribute . call ( disabledLink , key , value )
206+ }
207+ } )
208+ globalEnv . rawSetAttribute . call ( disabledLink , 'disabled' , 'true' )
209+
210+ const observer = getAutoRemoveObserver ( convertStyle , disabledLink )
211+
212+ return {
213+ disabledLink,
214+ observer,
215+ }
216+ }
217+
164218/**
165219 * Fetch link succeeded, replace placeholder with style tag
166220 * NOTE:
@@ -198,6 +252,10 @@ export function fetchLinkSuccess (
198252 if ( placeholder ) {
199253 const convertStyle = pureCreateElement ( 'style' )
200254
255+ // mini-css-extract-plugin in hmr mode updates css by finding the <link /> element and replacing it.
256+ // so we need to create a disabled link for the hmr to work
257+ const { disabledLink, observer } = getDisabledLink ( convertStyle , linkInfo , app )
258+
201259 handleConvertStyle (
202260 app ,
203261 address ,
@@ -207,9 +265,16 @@ export function fetchLinkSuccess (
207265 )
208266
209267 if ( placeholder . parentNode ) {
210- placeholder . parentNode . replaceChild ( convertStyle , placeholder )
268+ const parentNode = placeholder . parentNode
269+ globalEnv . rawWindow . __parentNode__ = parentNode
270+ parentNode . insertBefore ( convertStyle , placeholder )
271+ parentNode . insertBefore ( disabledLink , placeholder )
272+ parentNode . removeChild ( placeholder )
273+ observer . observe ( parentNode , { childList : true } )
211274 } else {
212275 microAppHead . appendChild ( convertStyle )
276+ microAppHead . appendChild ( disabledLink )
277+ observer . observe ( microAppHead , { childList : true } )
213278 }
214279
215280 // clear placeholder
0 commit comments