Skip to content

Commit 89ece42

Browse files
committed
fix: css variable removed when declared in wrong order
#518
1 parent 2f9cc65 commit 89ece42

File tree

4 files changed

+27
-2
lines changed

4 files changed

+27
-2
lines changed

packages/purgecss/__tests__/css-variables.test.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import PurgeCSS from "./../src/index";
2-
32
import { ROOT_TEST_EXAMPLES } from "./utils";
43

54
describe("purge unused css variables", () => {
@@ -25,4 +24,8 @@ describe("purge unused css variables", () => {
2524
expect(purgedCSS.includes("--unused-color")).toBe(false);
2625
expect(purgedCSS.includes("--button-color")).toBe(false);
2726
});
27+
it("keeps '--color-first:', '--wrong-order'", () => {
28+
expect(purgedCSS.includes("--color-first:")).toBe(true);
29+
expect(purgedCSS.includes("--wrong-order:")).toBe(true);
30+
});
2831
});

packages/purgecss/__tests__/test_examples/css-variables/variables.css

+4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
:root {
2+
--color-first: var(--wrong-order);
23
--primary-color: blue;
34
--secondary-color: indigo;
45
--tertiary-color: aqua;
56
--unused-color: violet;
67
--used-color: rebeccapurple;
78
--accent-color: orange;
9+
--wrong-order: yellow;
10+
--random: var(--not-existing);
811
}
912

1013
.button {
@@ -19,4 +22,5 @@
1922
.button:focus {
2023
background-color: var(--accent-color);
2124
color: var(--primary-color);
25+
border-color: var(--color-first);
2226
}

packages/purgecss/src/VariablesStructure.ts

+18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as postcss from "postcss";
2+
import { matchAll } from "./index";
23
import { StringRegExpArray } from "./types";
34

45
class VariableNode {
@@ -62,9 +63,26 @@ class VariablesStructure {
6263
}
6364

6465
removeUnused(): void {
66+
// check unordered usage
67+
for (const used of this.usedVariables) {
68+
const usedNode = this.nodes.get(used);
69+
if (usedNode) {
70+
const usedVariablesMatchesInDeclaration = matchAll(
71+
usedNode.value.value,
72+
/var\((.+?)[,)]/g
73+
);
74+
usedVariablesMatchesInDeclaration.forEach((usage) => {
75+
if (!this.usedVariables.has(usage[1])) {
76+
this.usedVariables.add(usage[1]);
77+
}
78+
});
79+
}
80+
}
81+
6582
for (const used of this.usedVariables) {
6683
this.setAsUsed(used);
6784
}
85+
6886
for (const [name, declaration] of this.nodes) {
6987
if (!declaration.isUsed && !this.isVariablesSafelisted(name)) {
7088
declaration.value.remove();

packages/purgecss/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ function isInPseudoClass(selector: selectorParser.Node): boolean {
243243
);
244244
}
245245

246-
function matchAll(str: string, regexp: RegExp): RegExpMatchArray[] {
246+
export function matchAll(str: string, regexp: RegExp): RegExpMatchArray[] {
247247
const matches: RegExpMatchArray[] = [];
248248
str.replace(regexp, function () {
249249
// eslint-disable-next-line prefer-rest-params

0 commit comments

Comments
 (0)