Version bump from 8.0.9 to 8.1.0 causes infinite loop with `next()`
See original GitHub issueSummary
I’ve written a postcss plugin that works well in 8.0.9, but runs into an infinite loop on 8.1.0 (as well as 8.1.4). I’m currently unable to find the cause (or whether I’m using anything that’s not explicitly in the postcss api that would warrant this issue).
Failing code
The lines of the plugin that are causing an infinite loop are:
while (
// Should go after initial comments and existing variable declarations
shouldGoAfter(decl, beforeNode)
) {
beforeNode = beforeNode.next();
}
and the minimal failing test case I can produce is the following:
.toggle-checkbox {
$height: 15px;
$width: 50px;
&-slider {
&:hover {
height: $height;
width: $width;
}
}
}
Additional Context:
- I’m using
poscss-scss
as the parser (version 3.0.2 when running withpostcss
8.1.0+) - Currently testing on node 10.18.1
What I’ve looked at so far
The crux of the bug appears to be that decl.next() === decl
is true. This appears to be after $height
has moved up to root
, but this didn’t seem to happen before 8.1.0.
I’ve looked through the release diff https://github.com/postcss/postcss/compare/8.0.9...8.1.0 and haven’t seen anything that might cause something similar to this, but did notice a subtle difference in behavior with markDirty
.
Next steps
I’ll do some more work a little later on getting a simpler plugin to reproduce the infinite loop, and for now I’ll set an exact dependency on 8.0.9.
I’m curious if there’s either a known or expected scenario where a node’s next()
would become itself, resulting in this loop. Also not sure if this is more closely related to postcss-scss
instead.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (2 by maintainers)
It happens, because in
8.1
we fixed an issue and nowRoot
is calling on any node’s changes.https://twitter.com/PostCSS/status/1310217954953490435
You have a problem in
child.prop.startsWith('$')
where you do not check that you already applied changes.There are a few options to fix the plugin:
Declaration
andRule
listeners and check that node was already processed.Once
instead ofRoot
.Can you try to replace here: