Preserve source files on CSS prepended from composed dependencies#173
Open
soreavis wants to merge 1 commit into
Open
Preserve source files on CSS prepended from composed dependencies#173soreavis wants to merge 1 commit into
soreavis wants to merge 1 commit into
Conversation
When a CSS module uses `composes: x from "./other.css"`, the CSS of that other file is copied into the output. It was copied as plain text, so PostCSS no longer knew which file each copied rule came from. Tools that run after postcss-modules need exactly that information. A bundler's URL rewriter, for example, has to turn `url(./image.png)` into a working path - and to do that it must know the directory of the file the rule was written in. With the information gone, those paths silently break. The copied CSS still produces exactly the same output as before. But now each dependency is also parsed once more under its own filename, and the file information from that parse is attached to the copied rules, matched one-to-one by position. If broken CSS makes two files' rules merge at a boundary, the one-to-one match no longer holds - in that case nothing is attached, which is the old behavior, rather than attaching the wrong file. Custom loaders that don't provide the new `finalSources` getter are unaffected. See madyankin#149.
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.
CSS collected from
composesdependencies is prepended as one concatenated string, so the re-parsed nodes carry nosource.input.file. Any plugin that runs afterwards and needs to resolve relative paths — bundler url rewriters are the practical case — has nothing to resolve against. That's the metadata half of #149, and it's what breaks background images in composed CSS modules over in vitejs/vite#15410.This keeps the prepend byte-identical (the snapshot suite passes untouched) and grafts per-file sources onto the prepended nodes afterwards: each dependency is re-parsed with its own
from, and sources are paired by position. A node-count guard skips the graft if malformed CSS merges nodes across a file boundary, so a node can end up unattributed as before but never attributed to the wrong file. Custom loaders without the newfinalSourcesgetter keep the old path.finalSourceis now derived fromfinalSources, and there's a test asserting the composed declarations keep their origin file.