-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
preprocessors.js
148 lines (139 loc) · 3.63 KB
/
preprocessors.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* Results on Node 20.3.1, Github Actions:
PostCSS sync: 70 ms (1.0 times faster)
PostCSS: 72 ms
LibSass sync: 118 ms (1.6 times slower)
LibSass: 123 ms (1.7 times slower)
Less: 139 ms (1.9 times slower)
Dart Sass sync: 219 ms (3.0 times slower)
Dart Sass: 397 ms (5.5 times slower)
*/
let { existsSync, readFileSync, writeFileSync } = require('node:fs')
let postcssSimpleVars = require('postcss-simple-vars')
let postcssNested = require('postcss-nested')
let postcssMixins = require('postcss-mixins')
let { join } = require('node:path')
let postcss = require('postcss')
let libsass = require('node-sass')
let sass = require('sass')
let less = require('less')
let example = join(__dirname, 'cache', 'bootstrap.css')
let origin = readFileSync(example).toString()
let i
let css = origin
.replace(/\s+filter:[^;}]+;?/g, '')
.replace('/*# sourceMappingURL=bootstrap.css.map */', '')
// PostCSS
let processor = postcss([postcssNested, postcssSimpleVars, postcssMixins])
let pcss = css
pcss += '$size: 100px;'
pcss += '@define-mixin icon { width: 16px; height: 16px; }'
for (i = 0; i < 100; i++) {
pcss += 'body { h1 { a { color: black; } } }'
pcss += 'h2 { width: $size; }'
pcss += '.search { fill: black; @mixin icon; }'
}
// Sass
let scss = css
scss += '$size: 100px;'
scss += '@mixin icon { width: 16px; height: 16px; }'
for (i = 0; i < 100; i++) {
scss += 'body { h1 { a { color: black; } } }'
scss += 'h2 { width: $size; }'
scss += '.search { fill: black; @include icon; }'
}
let scssFile = join(__dirname, 'cache', 'bootstrap.preprocessors.scss')
writeFileSync(scssFile, scss)
// Less
let lcss = css.replace(/--[-\w]+:\s*;/g, '')
lcss += '@size: 100px;'
lcss += '.icon() { width: 16px; height: 16px; }'
for (i = 0; i < 100; i++) {
lcss += 'body { h1 { a { color: black; } } }'
lcss += 'h2 { width: @size; }'
lcss += '.search { fill: black; .icon() }'
}
module.exports = {
maxTime: 15,
name: 'Preprocessors',
tests: [
{
defer: true,
fn: done => {
libsass.render({ data: scss }, () => done.resolve())
},
name: 'LibSass'
},
{
fn: () => {
libsass.renderSync({ data: scss })
},
name: 'LibSass sync'
},
{
defer: true,
fn: done => {
sass.render({ data: scss }, () => done.resolve())
},
name: 'Dart Sass'
},
{
fn: () => {
sass.renderSync({ data: scss })
},
name: 'Dart Sass sync'
},
{
defer: true,
fn: done => {
processor.process(pcss, { from: example, map: false }).then(() => {
done.resolve()
})
},
name: 'PostCSS'
},
{
defer: true,
fn: done => {
processor.process(pcss, { from: example, map: false }).css
done.resolve()
},
name: 'PostCSS sync'
},
{
defer: true,
fn: done => {
less.render(lcss, { math: 'strict' }, err => {
if (err) throw err
done.resolve()
})
},
name: 'Less'
}
]
}
let devPath = join(__dirname, '../postcss/lib/postcss.js')
if (existsSync(devPath)) {
let devPostcss = require(devPath)
let devProcessor = devPostcss([
postcssNested,
postcssSimpleVars,
postcssMixins
])
module.exports.tests.splice(6, 0, {
defer: true,
fn: done => {
devProcessor.process(pcss, { from: example, map: false }).then(() => {
done.resolve()
})
},
name: 'Next PostCSS'
})
module.exports.tests.splice(8, 0, {
defer: true,
fn: done => {
devProcessor.process(pcss, { from: example, map: false }).css
done.resolve()
},
name: 'Next PostCSS sync'
})
}