fix: Preserve escape sequences when sorting JS string literals#461
Merged
Boshen merged 2 commits intoMay 25, 2026
Merged
Conversation
When sorting class strings inside a JS string literal whose outer quote
is fixed by the surrounding context (e.g. a Vue `:class="cn('...')"`
attribute), the sorter operated on the cooked value and then wrote it
back as raw without re-encoding, dropping JS escapes like `\'` and
producing invalid JavaScript that failed the next parse.
Sort the raw source representation directly so escape sequences ride
along with their tokens, mirroring how `sortTemplateLiteral` already
handles quasis. This also removes the need to discriminate JS literals
from JSX attribute values (where backslashes are literal and divergence
between raw and cooked is driven by HTML entity decoding, not escapes).
The trade-off: literals that use a whitespace escape sequence as the
class separator look like one non-whitespace token in raw form, so we
skip sorting them. This shape has no realistic callers and rewriting
it would re-introduce the cooked → raw re-encoding we just eliminated.
90968c3 to
8ece5f2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Fixes #460
When sorting class strings inside a JS string literal whose outer quote is fixed by the surrounding context (e.g. a Vue
:class="cn('...')"attribute), the sorter operated on the cooked value and then wrote it back as raw without re-encoding, dropping JS escapes like\'and producing invalid JavaScript that failed the next parse.Sort the raw source representation directly so escape sequences ride along with their tokens, mirroring how
sortTemplateLiteralalready handles quasis. This also removes the need to discriminate JS literals from JSX attribute values (where backslashes are literal and divergence between raw and cooked is driven by HTML entity decoding, not escapes).The trade-off: literals that use a whitespace escape sequence as the class separator look like one non-whitespace token in raw form, so we skip sorting them. This shape has no realistic callers and rewriting it would re-introduce the cooked → raw re-encoding we just eliminated.