lwc
lwc copied to clipboard
[HMR] `swap*` APIs show stale content when swapping back and forth multiple times
The swapComponent
/swapStyle
/swapTemplate
APIs do not work correctly in the following scenario (using swapStyle
to illustrate):
/* initial state */ // works - A is rendered
swapStyle(a, b) // works - B is rendered
swapStyle(b, a) // works - A is rendered
swapStyle(a, b) // does not work! A is still rendered
The reason for this is this line:
https://github.com/salesforce/lwc/blob/e7377d29ee2f7f7a58a862a69d2ddfbcf96878e3/packages/%40lwc/engine-core/src/framework/hot-swaps.ts#L187
The swappedStyleMap
only ever grows – it never shrinks. So after swapping A and B a few times, we end up with the mappings:
A -> B
B -> A
Next, consider this code:
https://github.com/salesforce/lwc/blob/e7377d29ee2f7f7a58a862a69d2ddfbcf96878e3/packages/%40lwc/engine-core/src/framework/hot-swaps.ts#L110-L120
There is a visited
set to avoid infinite loops. However, if we have entries for both A -> B
and B -> A
, then calling this function with A
will always return A
. This is why the third swapStyle
above doesn't work.
Related: #4115
Minimal repro: https://github.com/nolanlawson/lwc-1/commit/3a135dfeeda434014a5b45f4f1b7156e78c6087f
This might not actually be an issue in practice, since our HMR implementation should re-evaluate the stylesheet
function every time, not based on its string content. TBD.