lwc icon indicating copy to clipboard operation
lwc copied to clipboard

[HMR] `swap*` APIs show stale content when swapping back and forth multiple times

Open nolanlawson opened this issue 4 months ago • 1 comments

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

nolanlawson avatar Apr 16 '24 19:04 nolanlawson

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.

nolanlawson avatar Apr 17 '24 20:04 nolanlawson