forked from kognise/water.css
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gulpfile.js
129 lines (112 loc) · 4.67 KB
/
gulpfile.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
const gulp = require('gulp')
const postcss = require('gulp-postcss')
const autoprefixer = require('autoprefixer')
const cssnano = require('cssnano')
const sourcemaps = require('gulp-sourcemaps')
const bytediff = require('gulp-bytediff')
const browserSync = require('browser-sync').create()
const chalk = require('chalk')
const rename = require('gulp-rename')
const filter = require('gulp-filter')
const flatten = require('gulp-flatten')
const sizereport = require('gulp-sizereport')
const postcssCssVariables = require('postcss-css-variables')
const postcssImport = require('postcss-import')
const postcssInlineSvg = require('postcss-inline-svg')
const postcssColorModFunction = require('postcss-color-mod-function').bind(null, {
/* Use `.toRGBLegacy()` as other methods can result in lots of decimals */
stringifier: color => color.toRGBLegacy(),
})
const paths = {
srcDir: 'src/*',
docsDir: '*',
styles: { src: 'src/builds/*.css', dest: 'dist' },
}
// https://stackoverflow.com/a/20732091
function humanFileSize(size) {
var i = Math.floor(Math.log(size) / Math.log(1024))
return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]
}
function formatByteMessage(source, data) {
const prettyStartSize = humanFileSize(data.startSize)
let message = ''
if (data.startSize !== data.endSize) {
const change = data.savings > 0 ? 'saved' : 'gained'
const prettySavings = humanFileSize(Math.abs(data.savings))
let prettyEndSize = humanFileSize(data.endSize)
if (data.endSize > data.startSize) prettyEndSize = chalk.yellow(prettyEndSize)
if (data.endSize < data.startSize) prettyEndSize = chalk.green(prettyEndSize)
message = chalk`${change} ${prettySavings} (${prettyStartSize} -> {bold ${prettyEndSize}})`
} else message = chalk`kept original filesize. ({bold ${prettyStartSize}})`
return chalk`{cyan ${source.padStart(12, ' ')}}: {bold ${data.fileName}} ${message}`
}
function style() {
const isLegacy = path => /legacy/.test(path)
const excludeModern = filter(file => isLegacy(file.path), { restore: true })
const excludeLegacy = filter(file => !isLegacy(file.path), { restore: true })
return (
gulp
.src(paths.styles.src)
// Add sourcemaps
.pipe(sourcemaps.init())
// Resolve imports, calculated colors and inlined SVG files
.pipe(postcss([postcssImport(), postcssColorModFunction(), postcssInlineSvg()]))
// * Process legacy builds *
.pipe(excludeModern)
// Inline variable values so CSS works in legacy browsers
.pipe(postcss([postcssCssVariables()]))
// Calculate size before autoprefixing
.pipe(bytediff.start())
// autoprefix
.pipe(postcss([autoprefixer()]))
// Write the amount gained by autoprefixing
.pipe(bytediff.stop(data => formatByteMessage('autoprefixer', data)))
.pipe(excludeModern.restore)
// * Process modern builds *
.pipe(excludeLegacy)
// Calculate size before autoprefixing
.pipe(bytediff.start())
// autoprefix modern builds
// TODO: Use separate browserslist to only apply prefixes needed in *modern* browsers
.pipe(postcss([autoprefixer()]))
// Write the amount gained by autoprefixing
.pipe(bytediff.stop(data => formatByteMessage('autoprefixer', data)))
.pipe(excludeLegacy.restore)
// Write the sourcemaps after making pre-minified changes
.pipe(sourcemaps.write('.'))
// Flatten output so files end up in dist/*, not dist/builds/*
.pipe(flatten())
// Write pre-minified styles
.pipe(gulp.dest(paths.styles.dest))
// Remove sourcemaps from the pipeline, only keep css
.pipe(filter('**/*.css'))
// Calculate size before minifying
.pipe(bytediff.start())
// Minify using cssnano, use extra-low precision while minifying inline SVGs
.pipe(postcss([cssnano({ preset: ['default', { svgo: { floatPrecision: 0 } }] })]))
// Write the amount saved by minifying
.pipe(bytediff.stop(data => formatByteMessage('cssnano', data)))
// Rename the files have the .min suffix
.pipe(rename({ suffix: '.min' }))
// Write the sourcemaps after making all changes
.pipe(sourcemaps.write('.'))
// Write the minified files
.pipe(gulp.dest(paths.styles.dest))
.pipe(sizereport({ gzip: true, total: false, title: 'SIZE REPORT' }))
// Stream any changes to browserSync
.pipe(browserSync.stream())
)
}
function watch() {
style()
browserSync.init({
server: {
baseDir: './',
},
startPath: 'index.html',
})
gulp.watch(paths.srcDir, style)
gulp.watch([paths.srcDir, paths.docsDir], browserSync.reload)
}
module.exports.style = style
module.exports.watch = watch