Skip to content

Commit e693d4f

Browse files
committed
Added: cssnext will now warn you when you have duplicates plugins
1 parent e54ab47 commit e693d4f

File tree

5 files changed

+171
-0
lines changed

5 files changed

+171
-0
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
- Added: cssnext will now warn you when you have duplicates plugins.
2+
This is a really common mistake, people include plugins that are already
3+
included in cssnext and maybe sometimes in an inaccurate position.
4+
**Most tutorial on the internet are wrong (probably 99%)
5+
and show provide duplicates in their examples.
6+
(eg: autoprefixer + cssnext - but cssnext already includes autoprefixer).**
7+
In order to fix this, here is a warning. You are welcome.
8+
[Read more about this issue](https://github.com/postcss/postcss/issues/764)
19
- Added: ``rem`` will now adjust its behavior according to browser option
210
(IE 9 and IE 10 will only have ``px`` in some places, where rem support is
311
buggy, per caniuse notes)

docs/content/usage.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ var output = cssnext(input, {
6161
})
6262
```
6363

64+
## `warnForDuplicates`
65+
66+
_(default: true)_
67+
68+
This option should be left with its default value, unless you really know what
69+
you are doing.
70+
Most tutorial on the internet are wrong and show provide duplicate
71+
(eg: autoprefixer + cssnext - but cssnext already includes autoprefixer).
72+
6473
**To know all available options, please check corresponding postcss plugin by
6574
browsing the
6675
[feature mapping](https://github.com/MoOx/postcss-cssnext/blob/master/src/features.js).**
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import tape from "tape"
2+
3+
import postcss from "postcss"
4+
import autoprefixer from "autoprefixer"
5+
import cssnext from ".."
6+
import { spotted } from "../warn-for-duplicates"
7+
8+
const reportFail = (t) => (error) => {
9+
console.log(error)
10+
t.fail()
11+
}
12+
13+
tape("cssnext warnForDuplicates option", (t) => {
14+
const messages = []
15+
spotted.length = 0 // reset spotted plugins
16+
const instance = postcss([
17+
cssnext({
18+
console: { log: (msg) => messages.push(msg) }
19+
}),
20+
])
21+
22+
instance.process("body{}").then(() => {
23+
t.equal(
24+
messages.length,
25+
0,
26+
"should not add warning if no duplicate"
27+
)
28+
t.end()
29+
}, reportFail(t))
30+
})
31+
32+
tape("cssnext warnForDuplicates option", (t) => {
33+
const messages = []
34+
spotted.length = 0 // reset spotted plugins
35+
const instance = postcss([
36+
autoprefixer(),
37+
cssnext({
38+
console: { log: (msg) => messages.push(msg) }
39+
}),
40+
])
41+
42+
instance.process("body{}").then(() => {
43+
t.ok(
44+
messages[0].indexOf("Warning: postcss-cssnext found a duplicate plugin")
45+
> -1,
46+
"should add warning if there are duplicates before"
47+
)
48+
t.end()
49+
}, reportFail(t))
50+
})
51+
52+
tape("cssnext warnForDuplicates option", (t) => {
53+
const messages = []
54+
spotted.length = 0 // reset spotted plugins
55+
const instance = postcss([
56+
autoprefixer(),
57+
cssnext({
58+
warnForDuplicates: false,
59+
console: { log: (msg) => messages.push(msg) }
60+
}),
61+
])
62+
63+
instance.process("body{}").then(() => {
64+
t.equal(
65+
messages.length,
66+
0,
67+
"should NOT add warning if there are duplicates but !warnForDuplicates"
68+
)
69+
t.end()
70+
}, reportFail(t))
71+
})
72+
73+
tape("cssnext warnForDuplicates option", (t) => {
74+
const messages = []
75+
spotted.length = 0 // reset spotted plugins
76+
const instance = postcss([
77+
cssnext({
78+
console: { log: (msg) => messages.push(msg) }
79+
}),
80+
autoprefixer(),
81+
])
82+
83+
instance.process("body{}").then(() => {
84+
t.ok(
85+
messages.length &&
86+
messages[0].indexOf("Warning: postcss-cssnext found a duplicate plugin")
87+
> -1,
88+
"should add warning if there are duplicates after"
89+
)
90+
t.end()
91+
}, reportFail(t))
92+
})

src/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import { isSupported } from "caniuse-api"
33

44
import libraryFeatures from "./features"
55
import featuresActivationMap from "./features-activation-map"
6+
import warnForDuplicates from "./warn-for-duplicates"
67

78
const plugin = postcss.plugin("postcss-cssnext", (options) => {
89
options = {
10+
console: console,
11+
warnForDuplicates: true,
912
features: {},
1013
// options.browsers is deliberately undefined by default to inherit
1114
// browserslist default behavior
@@ -69,6 +72,13 @@ const plugin = postcss.plugin("postcss-cssnext", (options) => {
6972
}
7073
})
7174

75+
if (options.warnForDuplicates) {
76+
processor.use(warnForDuplicates({
77+
keys: Object.keys(libraryFeatures),
78+
console: options.console
79+
}))
80+
}
81+
7282
return processor
7383
})
7484

src/warn-for-duplicates.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import postcss from "postcss"
2+
import color from "chalk"
3+
4+
const msg = (name) => (
5+
`Warning: postcss-cssnext found a duplicate plugin ('${ name }') ` +
6+
`in your postcss plugins. ` +
7+
`This might be inefficient. You should remove '${ name }' of you postcss ` +
8+
`plugin list since it's already included by postcss-cssnext.`
9+
)
10+
11+
let shouldGlobalWarn = true
12+
const globalWarning = (
13+
`Note: If, for a really specific reason, postcss-cssnext warnings are ` +
14+
`irrelevant for your use case, and you really know what you are doing, ` +
15+
`you can disable this warnings by setting 'warnForDuplicates' option of ` +
16+
`postcss-cssnext to 'false'.`
17+
)
18+
export const spotted = []
19+
20+
const warnForDuplicates = postcss.plugin(
21+
"postcss-warn-for-duplicates",
22+
(options) => {
23+
return (style, result) => {
24+
// https://github.com/postcss/postcss/issues/768
25+
const { keys, console: messenger } = options
26+
const pluginNames = []
27+
result.processor.plugins.forEach((plugin) => {
28+
const name = plugin.postcssPlugin
29+
if (
30+
pluginNames.indexOf(name) > -1 &&
31+
// warn for cssnext plugins only
32+
keys.indexOf(name) > -1 &&
33+
// show warning once
34+
spotted.indexOf(name) === -1
35+
) {
36+
messenger.log(color.yellow.bold(msg(name)))
37+
spotted.push(name)
38+
}
39+
else {
40+
pluginNames.push(name)
41+
}
42+
})
43+
44+
if (spotted.length > 0 && shouldGlobalWarn) {
45+
shouldGlobalWarn = false
46+
messenger.log(globalWarning)
47+
}
48+
}
49+
}
50+
)
51+
52+
export default warnForDuplicates

0 commit comments

Comments
 (0)