Preserve node raws when rehydrating a JSON AST#2100
Merged
Conversation
fromJSON() attached child nodes through the container constructor, which runs them back through append()/normalize(). For root-level children that re-applies insertion spacing normalization and overwrites each node's own raws.before with the previous sibling's, so toJSON() -> fromJSON() was not lossless: stylesheets with non-uniform blank lines between top-level rules came back with their spacing flattened. Rehydrate children separately and attach them directly, keeping the raws exactly as serialized.
Member
|
Thanks! |
Member
|
Released in 8.5.16. |
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.
fromJSON(root.toJSON())isn't lossless when a stylesheet has uneven spacing between its top-level nodes:toJSON()serializes everyraws.beforecorrectly — the loss happens on the way back.fromJSONbuilds the child nodes and then passes them to the container constructor, which appends them; for root children that re-runs the insertion spacing logic inRoot.normalize, overwriting each node's ownraws.beforewith the previous sibling's. So every top-level node after the first inherits the first one's spacing.It matters because round-tripping through JSON is meant to restore an AST exactly (e.g. caching a parsed AST), so a rehydrated root should stringify to the same CSS as the original.
I rehydrate the children and attach them directly instead of routing them through
append, leaving their raws untouched. Runtimeappend/insertion behavior is unchanged. Found it round-tripping the postcss-parser-tests fixtures; added a regression test andpnpm testis green.