-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathgulpfile.js
More file actions
170 lines (149 loc) · 5.13 KB
/
Copy pathgulpfile.js
File metadata and controls
170 lines (149 loc) · 5.13 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import Fs from 'node:fs'
import gulp from 'gulp'
import * as dartSass from 'sass'
import gulpSass from 'gulp-sass'
import cleancss from 'gulp-clean-css'
import csscomb from 'gulp-csscomb'
import rename from 'gulp-rename'
import replace from 'gulp-replace'
import gulpIf from 'gulp-if'
import merge from 'merge-stream'
import autoprefixer from 'gulp-autoprefixer'
import prefixSelector from 'postcss-prefix-selector'
import prefixer from 'postcss-prefixer'
import postcss from 'gulp-postcss'
import { readFileSync } from 'fs'
const sass = gulpSass(dartSass)
const pkg = JSON.parse(readFileSync('./package.json', 'utf8'))
const { version } = pkg
const DIST_PATH = './dist'
const DOCS_PATH = '../spectre-docs'
// ---------------------------------------------------------------------------------------------------------------------
// lib scripts
// ---------------------------------------------------------------------------------------------------------------------
/**
* Build for distribution
*/
export function build () {
return gulp
.src('./src/*.scss')
.pipe(replace(/%VERSION%/g, `v${version}`))
.pipe(sass({ style: 'expanded' })
.on('error', sass.logError)
)
.pipe(autoprefixer())
.pipe(csscomb())
.pipe(gulp.dest(DIST_PATH))
.pipe(cleancss())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(DIST_PATH))
}
/**
* Watch and rebuild for development
*/
export function watch () {
return gulp.watch('./**/*.scss', { ignoreInitial: false }, build)
}
// ---------------------------------------------------------------------------------------------------------------------
// docs scripts
// ---------------------------------------------------------------------------------------------------------------------
/**
* Build and save docs stylesheets
*/
export function buildDocs () {
// copy docs stylesheets
const output = `${DOCS_PATH}/.vitepress/theme/styles/spectre`
const options = { output, minOnly: true }
const streams = [isolate('namespace', '.vp-doc', options)]
// update version string
const index = `${DOCS_PATH}/index.md`
if (Fs.existsSync(index)) {
streams.push(
gulp
.src(index, { base: '.' })
.pipe(replace(/tagline: ".+?"/, `tagline: "Latest version: v${version}"`))
.pipe(gulp.dest('.'))
)
}
return merge(streams)
}
/**
* Watch and rebuild docs stylesheets for development
*/
export function watchDocs () {
return gulp.watch(`${DIST_PATH}/spectre.css`, { ignoreInitial: false }, buildDocs)
}
/**
* Build and watch main lib, then namespace and save docs stylesheet to parallel docs repo
*/
export const docs = Fs.existsSync(DOCS_PATH)
? gulp.parallel(watch, watchDocs)
: function () {
console.log(`
The "spectre-docs" folder / repo was not found.
To build only "spectre-css" run "watch" or "build".
`)
return Promise.resolve()
}
// ---------------------------------------------------------------------------------------------------------------------
// helpers
// ---------------------------------------------------------------------------------------------------------------------
/**
* Isolate Options
*
* @typedef {Object} IsolateOptions
* @property {string|string[]} [names] The names of files to prefix, defaults to "*" (all)
* @property {string} [output] The output folder, defaults to './dist' (overwrites files)
* @property {boolean} [minOnly] Output minified files only, defaults to false
*/
/**
* Utility function to isolate classes and save files
*
* @param {'prefix'|'namespace'} type The operation to run
* @param {string} value The string to use in the operation
* @param {IsolateOptions} [options] Options to customise the isolation
*
* @example
*
* // build all files, namespace to main, and save to dist/isolated
* isolate('namespace', 'main')
*
* // build only main and exp, namespace to .docs, and save to dist/isolated
* isolate('namespace', '.docs', { names: ['spectre', 'spectre-exp'] })
*
* // build all files, prefix with `s-`, save minified files only to
* isolate('prefix', 's-', { output: '../docs/styles', minOnly: true })
*/
function isolate (type, value, options = {}) {
// defaults
options = Object.assign({
names: '*',
output: `${DIST_PATH}/${type}`,
minOnly: false
}, options)
// options
let { names, output, minOnly } = options
// paths
// BUG: cannot get gulp.src() to ignore .css.min files with '!*.min.css' pattern so hardcoding names 😕
names = names === '*'
? ['spectre', 'spectre-exp', 'spectre-icons']
: typeof names === 'string'
? [names]
: names
const include = `${DIST_PATH}/{${names.join(',')}}.css`
// setup
const exclude = [/\b:root\b/, /\bhtml\S*/, /\bbody\S*/]
const plugin = type === 'namespace'
? prefixSelector({ prefix: value, exclude })
: prefixer({ prefix: value.replace(/^\./, ''), ignore: exclude })
// task
return gulp
.src(include)
.pipe(postcss([plugin]))
// output
.pipe(gulpIf(!minOnly, gulp.dest(output)))
// minified
.pipe(cleancss())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(output))
}