Skip to content

Commit 46a3b8e

Browse files
akdetrickMadLittleMods
authored andcommitted
Add opts.preserveInjectedVariables (#74)
Adds `opts.preserveInjectedVariables`, which when set to false, removes custom property declarations added via `opts.variables`.
1 parent 455cc21 commit 46a3b8e

File tree

7 files changed

+85
-10
lines changed

7 files changed

+85
-10
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,13 @@ Can be a simple key-value pair or an object with a `value` property and an optio
368368

369369
The object keys are automatically prefixed with `--` (according to CSS custom property syntax) if you do not provide it.
370370

371+
### `preserveInjectedVariables` (default: `true`)
372+
373+
Whether to preserve the custom property declarations inserted via the `variables` option from final output.
374+
375+
A typical use case is [CSS Modules](https://github.com/css-modules/css-modules), where you would want to avoid
376+
repeating custom property definitions in every module passed through this plugin. Setting this option to `false`
377+
prevents JS-injected variables from appearing in output CSS.
371378

372379
```js
373380
var postcss = require('postcss');

index.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ var defaults = {
6262
// Define variables via JS
6363
// Simple key-value pair
6464
// or an object with a `value` property and an optional `isImportant` bool property
65-
variables: {}
65+
variables: {},
66+
// Preserve variables injected via JS with the `variables` option above
67+
// before serializing to CSS (`false` will remove these variables from output)
68+
preserveInjectedVariables: true
6669
};
6770

6871
module.exports = postcss.plugin('postcss-css-variables', function(options) {
@@ -82,6 +85,10 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) {
8285
// We use this because we don't want to modify the AST when we still need to reference these later on
8386
var nodesToRemoveAtEnd = [];
8487

88+
// Keep track of the injected from `opts.variables` to remove at the end
89+
// if user passes `opts.preserveInjectedVariables = false`
90+
var injectedDeclsToRemoveAtEnd = [];
91+
8592
// Map of variable names to a list of declarations
8693
var map = {};
8794

@@ -106,6 +113,11 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) {
106113
});
107114
variableRootRule.append(varDecl);
108115

116+
// Collect JS-injected variables for removal if `opts.preserveInjectedVariables = false`
117+
if (!opts.preserveInjectedVariables) {
118+
injectedDeclsToRemoveAtEnd.push(varDecl);
119+
}
120+
109121
// Add the entry to the map
110122
prevVariableMap[variableName] = (prevVariableMap[variableName] || []).concat({
111123
decl: varDecl,
@@ -249,6 +261,11 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) {
249261
// We clean up at the end because we don't want to modify the AST when we still need to reference these later on
250262
nodesToRemoveAtEnd.forEach(cleanUpNode);
251263

264+
// Clean up JS-injected variables marked for removal
265+
injectedDeclsToRemoveAtEnd.forEach(function(injectedDecl) {
266+
injectedDecl.remove();
267+
});
268+
252269

253270
//console.log('map', map);
254271

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.box1 {
2+
width: var(--js-defined1);
3+
height: var(--js-defined2);
4+
background: var(--js-defined-no-prefix);
5+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.box1 {
2+
width: 75px;
3+
width: var(--js-defined1);
4+
height: 80px;
5+
height: var(--js-defined2);
6+
background: #ff0000;
7+
background: var(--js-defined-no-prefix);
8+
}

test/fixtures/js-defined-preserve.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.box1 {
2+
width: var(--js-defined1);
3+
height: var(--js-defined2);
4+
background: var(--js-defined-no-prefix);
5+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
:root {
2+
--js-defined-no-prefix: #ff0000;
3+
}
4+
:root {
5+
--js-defined2: 80px;
6+
}
7+
:root {
8+
--js-defined1: 75px;
9+
}
10+
11+
.box1 {
12+
width: 75px;
13+
width: var(--js-defined1);
14+
height: 80px;
15+
height: var(--js-defined2);
16+
background: #ff0000;
17+
background: var(--js-defined-no-prefix);
18+
}

test/test.js

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ var cssvariables = require('../');
1212

1313
var CleanCSS = require('clean-css');
1414

15+
var MOCK_JS_VARIABLES = {
16+
'--js-defined1': '75px',
17+
'--js-defined2': {
18+
value: '80px'
19+
},
20+
// Should be automatically prefixed with `--`
21+
'js-defined-no-prefix': '#ff0000'
22+
};
1523

1624
var testPlugin = function(filePath, expectedFilePath, options) {
1725
options = options || {};
@@ -146,20 +154,27 @@ describe('postcss-css-variables', function() {
146154
test(
147155
'should work with JS defined variables',
148156
'js-defined',
157+
{ variables: MOCK_JS_VARIABLES }
158+
);
159+
test(
160+
'should preserve -- declarations and var() values with `options.variables` AND `options.preserve`',
161+
'js-defined-preserve',
162+
{
163+
variables: MOCK_JS_VARIABLES,
164+
preserve: true
165+
}
166+
);
167+
test(
168+
'should preserve var() values and clean injected declarations with `options.variables` AND `options.preserve` AND `options.preserveInjectedVariables: false`',
169+
'js-defined-preserve-injected',
149170
{
150-
variables: {
151-
'--js-defined1': '75px',
152-
'--js-defined2': {
153-
value: '80px'
154-
},
155-
// Should be automatically prefixed with `--`
156-
'js-defined-no-prefix': '#ff0000'
157-
}
171+
variables: MOCK_JS_VARIABLES,
172+
preserve: true,
173+
preserveInjectedVariables: false,
158174
}
159175
);
160176
});
161177

162-
163178
describe('with `options.preserve`', function() {
164179
test(
165180
'preserves variables when `preserve` is `true`',

0 commit comments

Comments
 (0)