fix: processVanillaFile fileScopes race #1585
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
processVanillaFile
(1) awaits while serializing css for each fileScope. For a file with multiple fileScopes (which happens when one.css.ts
file imports another), it will yield to the event loop before callingtransformCss
on the next fileScope.If the integration is handling multiple files concurrently, it could yield to another
processVanillaFile
(2).Since all
processVanillaFile
calls share one adapaterStack, (2) could push its adapter onto the stack and then yield back to (1) while (2) is awaiting serialization.If this happens, currentAdapter will point to the adapter of (2) for the
transformCss
of the next fileScope in (1).This causes the
markCompositionUsed
called bytransformCss
to update the wrong adapter.unusedCompositions
of (1) would then include an identifier that was actually used. The identifier is then stripped and any selectors that referenced it will not work.The new test in
processVanillaFile.test.ts
fails without this change.Solution
Add the scoped adapter to the stack before calling functions that use it (
evalCode
andtransformCss
) and remove the adapter before any awaits. This waycurrentAdapter
will always point to the relevant adapter.Context
Pretty sure this is what's going on here: #654