Skip to content

fix: Preserve escape sequences when sorting JS string literals#461

Merged
Boshen merged 2 commits into
tailwindlabs:mainfrom
leaysgur:fix/preserve-escapes-in-sorted-string-literals
May 25, 2026
Merged

fix: Preserve escape sequences when sorting JS string literals#461
Boshen merged 2 commits into
tailwindlabs:mainfrom
leaysgur:fix/preserve-escapes-in-sorted-string-literals

Conversation

@leaysgur
Copy link
Copy Markdown
Contributor

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 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.

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.
@leaysgur leaysgur force-pushed the fix/preserve-escapes-in-sorted-string-literals branch from 90968c3 to 8ece5f2 Compare May 25, 2026 02:43
@Boshen Boshen merged commit 2b6f3c2 into tailwindlabs:main May 25, 2026
1 check passed
@leaysgur leaysgur deleted the fix/preserve-escapes-in-sorted-string-literals branch May 25, 2026 04:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

class sort error

2 participants