gulpfile.js 11.6 KB
Newer Older
C
codecalm 已提交
1
const gulp = require('gulp'),
C
codecalm 已提交
2
	debug = require('gulp-debug'),
C
codecalm 已提交
3
	clean = require('gulp-clean'),
P
Paweł Kuna 已提交
4
	sass = require('gulp-sass')(require('node-sass')),
C
codecalm 已提交
5
	postcss = require('gulp-postcss'),
C
codecalm 已提交
6
	header = require('gulp-header'),
C
codecalm 已提交
7
	cleanCSS = require('gulp-clean-css'),
C
codecalm 已提交
8
	rtlcss = require('gulp-rtlcss'),
9
	minifyJS = require('gulp-terser'),
C
codecalm 已提交
10
	rename = require('gulp-rename'),
C
codecalm 已提交
11
	purgecss = require('gulp-purgecss'),
C
codecalm 已提交
12
	rollupStream = require('@rollup/stream'),
C
codecalm 已提交
13 14
	rollupBabel = require('rollup-plugin-babel'),
	rollupCleanup = require('rollup-plugin-cleanup'),
P
Paweł Kuna 已提交
15
	{ nodeResolve } = require('@rollup/plugin-node-resolve'),
C
codecalm 已提交
16
	rollupCommonjs = require('@rollup/plugin-commonjs'),
C
codecalm 已提交
17
	rollupReplace = require('@rollup/plugin-replace'),
C
codecalm 已提交
18 19
	vinylSource = require('vinyl-source-stream'),
	vinylBuffer = require('vinyl-buffer'),
C
codecalm 已提交
20
	critical = require('critical').stream,
C
codecalm 已提交
21
	browserSync = require('browser-sync'),
C
codecalm 已提交
22
	glob = require('glob'),
C
codecalm 已提交
23
	spawn = require('cross-spawn'),
C
codecalm 已提交
24 25 26
	fs = require('fs'),
	path = require('path'),
	YAML = require('yaml'),
C
codecalm 已提交
27
	yargs = require('yargs/yargs'),
C
codecalm 已提交
28 29
	cp = require('child_process'),
	pkg = require('./package.json'),
C
codecalm 已提交
30
	year = new Date().getFullYear(),
P
Paweł Kuna 已提交
31
	argv = yargs(process.argv).argv
C
codecalm 已提交
32

C
codecalm 已提交
33 34 35
let BUILD = false,
	distDir = './.tmp',
	demoDir = './.tmp',
P
Paweł Kuna 已提交
36
	srcDir = './src'
C
codecalm 已提交
37

C
codecalm 已提交
38 39 40
/**
 * Enable BUILD mode and set directories
 */
C
codecalm 已提交
41
gulp.task('build-on', (cb) => {
P
Paweł Kuna 已提交
42 43 44
	BUILD = true
	distDir = './dist'
	demoDir = './demo'
C
codecalm 已提交
45

P
Paweł Kuna 已提交
46 47
	cb()
})
C
codecalm 已提交
48 49 50 51

/**
 * Return banner added to CSS and JS dist files
 */
C
codecalm 已提交
52 53 54 55 56 57 58 59 60
const getBanner = () => {
	return `/*!
* Tabler v${pkg.version} (${pkg.homepage})
* @version ${pkg.version}
* @link ${pkg.homepage}
* Copyright 2018-${year} The Tabler Authors
* Copyright 2018-${year} codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
P
Paweł Kuna 已提交
61 62
`
}
C
codecalm 已提交
63

C
codecalm 已提交
64 65 66
/**
 * Array.flat polyfill
 */
C
codecalm 已提交
67 68
if (!Array.prototype.flat) {
	Object.defineProperty(Array.prototype, 'flat', {
C
codecalm 已提交
69 70
		value: function (depth = 1) {
			return this.reduce(function (flat, toFlatten) {
P
Paweł Kuna 已提交
71 72
				return flat.concat((Array.isArray(toFlatten) && (depth > 1)) ? toFlatten.flat(depth - 1) : toFlatten)
			}, [])
C
codecalm 已提交
73
		}
P
Paweł Kuna 已提交
74
	})
C
codecalm 已提交
75 76
}

C
codecalm 已提交
77
/**
C
codecalm 已提交
78
 * Import tabler-icons form npm and generate Jekyll `.yml` data files
C
codecalm 已提交
79
 */
C
codecalm 已提交
80 81
gulp.task('svg-icons', (cb) => {
	const prepareSvgFile = (svg) => {
P
Paweł Kuna 已提交
82 83
		return svg.replace(/\n/g, '').replace(/>\s+</g, '><')
	}
C
codecalm 已提交
84

C
codecalm 已提交
85
	const generateIconsYml = (dir, filename) => {
P
Paweł Kuna 已提交
86 87
		const files = glob.sync(dir)
		let svgList = {}
C
codecalm 已提交
88

C
codecalm 已提交
89
		files.forEach((file) => {
P
Paweł Kuna 已提交
90 91 92
			const basename = path.basename(file, '.svg')
			svgList[basename] = prepareSvgFile(fs.readFileSync(file).toString())
		})
C
codecalm 已提交
93

P
Paweł Kuna 已提交
94 95
		fs.writeFileSync(filename, YAML.stringify(svgList))
	}
C
codecalm 已提交
96

P
Paweł Kuna 已提交
97
	generateIconsYml("./node_modules/@tabler/icons/icons/*.svg", `${srcDir}/pages/_data/icons.yml`)
C
codecalm 已提交
98

P
Paweł Kuna 已提交
99 100
	cb()
})
C
codecalm 已提交
101

C
codecalm 已提交
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
/**
 * Generate CHANGELOG.md
 */
gulp.task('changelog', (cb) => {
	const content = YAML.parse(fs.readFileSync('./src/pages/_data/changelog.yml', 'utf8'))
	let readme = `# Changelog

All notable changes to this project will be documented in this file.\n`

	content.forEach((change) => {
		readme += `\n\n## \`${change.version}\` - ${change.date}\n\n`

		if(change.description) {
			readme += `**${change.description}**\n\n`
		}

		change.changes.forEach((line) => {
			readme += `- ${line}\n`
		})

		console.log(change.version);
	})

	fs.writeFileSync('CHANGELOG.md', readme)

	cb()
})

C
codecalm 已提交
130 131 132
/**
 * Check unused Jekyll partials
 */
C
codecalm 已提交
133
gulp.task('unused-files', (cb) => {
P
Paweł Kuna 已提交
134
	let foundFiles = []
C
codecalm 已提交
135

C
codecalm 已提交
136
	glob.sync(`${srcDir}/pages/**/*.{html,md}`).forEach((file) => {
P
Paweł Kuna 已提交
137
		let fileContent = fs.readFileSync(file)
C
codecalm 已提交
138

C
codecalm 已提交
139
		fileContent.toString().replace(/\{% include(_cached)? ([a-z0-9\/_-]+\.html)/g, (f, c, filename) => {
P
Paweł Kuna 已提交
140
			filename = `${srcDir}/pages/_includes/${filename}`
C
codecalm 已提交
141 142

			if (!foundFiles.includes(filename)) {
P
Paweł Kuna 已提交
143
				foundFiles.push(filename)
C
codecalm 已提交
144
			}
P
Paweł Kuna 已提交
145 146
		})
	})
C
codecalm 已提交
147

P
Paweł Kuna 已提交
148
	let includeFiles = glob.sync(`${srcDir}/pages/_includes/**/*.html`)
C
codecalm 已提交
149

C
codecalm 已提交
150
	includeFiles.forEach((file) => {
C
codecalm 已提交
151
		if (!foundFiles.includes(file)) {
P
Paweł Kuna 已提交
152
			console.log('file', file)
C
codecalm 已提交
153
		}
P
Paweł Kuna 已提交
154
	})
C
codecalm 已提交
155

P
Paweł Kuna 已提交
156 157
	cb()
})
C
codecalm 已提交
158

C
codecalm 已提交
159
/**
C
codecalm 已提交
160
 * Clean `dist` folder before build
C
codecalm 已提交
161
 */
C
codecalm 已提交
162
gulp.task('clean-dirs', () => {
C
codecalm 已提交
163
	return gulp
C
codecalm 已提交
164
		.src(`{${distDir}/*,${demoDir}/*}`, { read: false })
P
Paweł Kuna 已提交
165 166
		.pipe(clean())
})
C
codecalm 已提交
167

C
codecalm 已提交
168
gulp.task('clean-jekyll', (cb) => {
C
codecalm 已提交
169
	return spawn('bundle', ['exec', 'jekyll', 'clean'], { stdio: 'inherit' })
P
Paweł Kuna 已提交
170 171
		.on('close', cb)
})
C
codecalm 已提交
172

C
codecalm 已提交
173
/**
C
codecalm 已提交
174
 * Compile SASS to CSS and move it to dist directory
C
codecalm 已提交
175
 */
C
codecalm 已提交
176
gulp.task('sass', () => {
C
fix rtl  
codecalm 已提交
177
	return gulp
178
		.src(argv.withPlugins || BUILD ? `${srcDir}/scss/!(_)*.scss` : `${srcDir}/scss/+(tabler|demo).scss`)
C
codecalm 已提交
179
		.pipe(debug())
C
codecalm 已提交
180 181
		.pipe(sass({
			style: 'expanded',
C
codecalm 已提交
182
			precision: 7,
C
codecalm 已提交
183 184
			importer: (url, prev, done) => {
				if (url[0] === '~') {
P
Paweł Kuna 已提交
185
					url = path.resolve('node_modules', url.substr(1))
C
codecalm 已提交
186 187
				}

P
Paweł Kuna 已提交
188
				return { file: url }
C
codecalm 已提交
189 190 191 192 193 194 195 196
			},
		}).on('error', sass.logError))
		.pipe(postcss([
			require('autoprefixer'),
		]))
		.pipe(gulp.dest(`${distDir}/css/`))
		.pipe(browserSync.reload({
			stream: true,
C
fix rtl  
codecalm 已提交
197
		}));
P
Paweł Kuna 已提交
198
})
C
codecalm 已提交
199

C
fix rtl  
codecalm 已提交
200 201 202 203 204 205 206 207 208
gulp.task('css-rtl', function () {
	return gulp.src(`${distDir}/css/*.css`)
		.pipe(rtlcss())
		.pipe(rename((path) => {
			path.basename += '.rtl'
		}))
		.pipe(gulp.dest(`${distDir}/css/`))
});

C
codecalm 已提交
209 210 211
/**
 * CSS minify
 */
P
Paweł Kuna 已提交
212
gulp.task('css-minify', function () {
C
codecalm 已提交
213 214 215 216
	return gulp.src(`${distDir}/css/!(*.min).css`)
		.pipe(debug())
		.pipe(cleanCSS())
		.pipe(rename((path) => {
P
Paweł Kuna 已提交
217
			path.basename += '.min'
C
codecalm 已提交
218
		}))
P
Paweł Kuna 已提交
219 220
		.pipe(gulp.dest(`${distDir}/css/`))
})
C
codecalm 已提交
221

C
codecalm 已提交
222 223 224
/**
 * Compile JS files to dist directory
 */
P
Paweł Kuna 已提交
225 226 227 228 229 230 231
let cache = {}

const compileJs = function (name, mjs = false) {
	if (!cache[name]) {
		cache[name] = null
	}

C
codecalm 已提交
232
	const g = rollupStream({
P
Paweł Kuna 已提交
233 234
		input: `${srcDir}/js/${name}.js`,
		cache: cache[name],
C
codecalm 已提交
235
		output: {
P
Paweł Kuna 已提交
236 237 238
			name: `${name}.js`,
			format: mjs ? 'es' : 'umd',
			...(mjs ? { exports: 'named' } : {})
C
codecalm 已提交
239 240
		},
		plugins: [
C
codecalm 已提交
241 242
			rollupReplace({
				'process.env.NODE_ENV': JSON.stringify(BUILD ? 'production' : 'development'),
243
				preventAssignment: false
C
codecalm 已提交
244
			}),
C
codecalm 已提交
245 246 247 248 249 250 251 252 253
			rollupBabel({
				exclude: 'node_modules/**'
			}),
			nodeResolve(),
			rollupCommonjs(),
			rollupCleanup()
		]
	})
		.on('bundle', (bundle) => {
P
Paweł Kuna 已提交
254
			cache[name] = bundle
C
codecalm 已提交
255
		})
P
Paweł Kuna 已提交
256
		.pipe(vinylSource(`${name}.js`))
C
codecalm 已提交
257
		.pipe(vinylBuffer())
C
codecalm 已提交
258
		.pipe(rename((path) => {
P
Paweł Kuna 已提交
259
			path.dirname = ''
C
codecalm 已提交
260 261 262 263
		}))
		.pipe(gulp.dest(`${distDir}/js/`))
		.pipe(browserSync.reload({
			stream: true,
P
Paweł Kuna 已提交
264
		}))
C
codecalm 已提交
265 266

	if (BUILD) {
267 268 269 270
		g.pipe(minifyJS())
			.pipe(rename((path) => {
				path.extname = '.min.js'
			}))
P
Paweł Kuna 已提交
271
			.pipe(gulp.dest(`${distDir}/js/`))
C
codecalm 已提交
272 273
	}

P
Paweł Kuna 已提交
274 275 276 277 278 279 280 281 282 283 284 285 286
	return g
}

/**
 * Compile JS files to dist directory
 */
gulp.task('js', () => {
	return compileJs('tabler')
})

gulp.task('js-demo', () => {
	return compileJs('demo')
})
C
codecalm 已提交
287

288 289 290 291
gulp.task('js-demo-theme', () => {
	 return compileJs('demo-theme')
})

292 293 294
/**
 * Compile JS module files to dist directory
 */
P
Paweł Kuna 已提交
295 296 297 298 299
gulp.task('mjs', () => {
	return compileJs('tabler.esm', true)
})

let cacheEsm
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
gulp.task('mjs', () => {
	const g = rollupStream({
		input: `${srcDir}/js/tabler.esm.js`,
		cache: cacheEsm,
		output: {
			name: 'tabler.esm.js',
			format: 'es',
			exports: 'named'
		},
		plugins: [
			rollupReplace({
				'process.env.NODE_ENV': JSON.stringify(BUILD ? 'production' : 'development'),
				preventAssignment: false
			}),
			rollupBabel({
				exclude: 'node_modules/**'
			}),
			nodeResolve(),
			rollupCommonjs(),
			rollupCleanup()
		]
	})
		.on('bundle', (bundle) => {
P
Paweł Kuna 已提交
323
			cacheEsm = bundle
324 325 326 327
		})
		.pipe(vinylSource('tabler.esm.js'))
		.pipe(vinylBuffer())
		.pipe(rename((path) => {
P
Paweł Kuna 已提交
328
			path.dirname = ''
329 330 331 332
		}))
		.pipe(gulp.dest(`${distDir}/js/`))
		.pipe(browserSync.reload({
			stream: true,
P
Paweł Kuna 已提交
333
		}))
334 335

	if (BUILD) {
336 337 338 339
		g.pipe(minifyJS())
			.pipe(rename((path) => {
				path.extname = '.min.js'
			}))
P
Paweł Kuna 已提交
340
			.pipe(gulp.dest(`${distDir}/js/`))
341 342
	}

P
Paweł Kuna 已提交
343 344
	return g
})
345

C
codecalm 已提交
346 347 348
/**
 * Watch Jekyll files and build it to demo directory
 */
C
codecalm 已提交
349
gulp.task('watch-jekyll', (cb) => {
P
Paweł Kuna 已提交
350
	browserSync.notify('Building Jekyll')
351
	return spawn('bundle', ['exec', 'jekyll', 'build', '--watch', '--incremental', '--destination', demoDir, '--trace'], { stdio: 'inherit' })
P
Paweł Kuna 已提交
352 353
		.on('close', cb)
})
C
codecalm 已提交
354

C
codecalm 已提交
355 356 357
/**
 * Build Jekyll files do demo directory
 */
C
codecalm 已提交
358
gulp.task('build-jekyll', (cb) => {
P
Paweł Kuna 已提交
359
	var env = Object.create(process.env)
C
codecalm 已提交
360

P
Paweł Kuna 已提交
361 362 363 364
	if (argv.preview) {
		env.JEKYLL_ENV = 'preview'
	} else {
		env.JEKYLL_ENV = 'production'
C
codecalm 已提交
365
	}
C
codecalm 已提交
366

P
Paweł Kuna 已提交
367 368 369 370 371 372
	return spawn('bundle', ['exec', 'jekyll', 'build', '--destination', demoDir, '--trace'], {
		env: env,
		stdio: 'inherit'
	})
		.on('close', cb)
})
C
codecalm 已提交
373

C
sitemap  
codecalm 已提交
374 375 376
gulp.task('build-cleanup', () => {
	return gulp
		.src(`${demoDir}/redirects.json`, { read: false, allowEmpty: true })
P
Paweł Kuna 已提交
377 378
		.pipe(clean())
})
C
sitemap  
codecalm 已提交
379

C
codecalm 已提交
380
gulp.task('build-purgecss', (cb) => {
P
Paweł Kuna 已提交
381
	if (argv.preview) {
C
codecalm 已提交
382 383 384 385 386 387 388
		return gulp.src('demo/dist/{libs,css}/**/*.css')
			.pipe(purgecss({
				content: ['demo/**/*.html']
			}))
			.pipe(gulp.dest('demo/dist/css'))
	}

P
Paweł Kuna 已提交
389 390
	cb()
})
C
codecalm 已提交
391 392

gulp.task('build-critical', (cb) => {
P
Paweł Kuna 已提交
393
	if (argv.preview) {
C
codecalm 已提交
394 395 396 397 398 399
		return gulp
			.src('demo/**/*.html')
			.pipe(
				critical({
					base: 'demo/',
					inline: true,
C
codecalm 已提交
400 401 402 403 404 405 406
					css: ['demo/dist/css/tabler.css'],
					ignore: {
						atrule: ['@font-face', '@import'],
						decl: (node, value) => {
							/url\(/.test(value)
						},
					},
C
codecalm 已提交
407 408 409
				})
			)
			.on('error', err => {
P
Paweł Kuna 已提交
410
				console.log(err.message)
C
codecalm 已提交
411
			})
P
Paweł Kuna 已提交
412
			.pipe(gulp.dest('demo'))
C
codecalm 已提交
413 414
	}

P
Paweł Kuna 已提交
415 416
	cb()
})
C
codecalm 已提交
417

C
codecalm 已提交
418 419 420
/**
 * Watch JS and SCSS files
 */
C
codecalm 已提交
421
gulp.task('watch', (cb) => {
P
Paweł Kuna 已提交
422
	gulp.watch('./src/scss/**/*.scss', gulp.series('sass'))
423
	gulp.watch('./src/js/**/*.js', gulp.parallel('js', 'mjs', gulp.parallel('js-demo', 'js-demo-theme')))
P
Paweł Kuna 已提交
424 425
	cb()
})
C
codecalm 已提交
426

C
codecalm 已提交
427 428 429
/**
 * Create BrowserSync server
 */
C
codecalm 已提交
430
gulp.task('browser-sync', () => {
C
codecalm 已提交
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
	browserSync({
		watch: true,
		server: {
			baseDir: demoDir,
			routes: {
				'/node_modules': 'node_modules',
				'/dist/css': `${distDir}/css`,
				'/dist/js': `${distDir}/js`,
				'/dist/img': `${srcDir}/img`,
				'/static': `${srcDir}/static`,
			},
		},
		port: 3000,
		open: false,
		host: 'localhost',
		notify: false,
		reloadOnRestart: true
P
Paweł Kuna 已提交
448 449
	})
})
C
codecalm 已提交
450

C
codecalm 已提交
451 452 453
/**
 * Copy libs used in tabler from npm to dist directory
 */
C
codecalm 已提交
454
gulp.task('copy-libs', (cb) => {
P
Paweł Kuna 已提交
455
	const allLibs = require(`${srcDir}/pages/_data/libs`)
C
codecalm 已提交
456

P
Paweł Kuna 已提交
457
	let files = []
C
codecalm 已提交
458

C
codecalm 已提交
459
	Object.keys(allLibs.js).forEach((lib) => {
P
Paweł Kuna 已提交
460 461
		files.push(Array.isArray(allLibs.js[lib]) ? allLibs.js[lib] : [allLibs.js[lib]])
	})
C
codecalm 已提交
462

C
codecalm 已提交
463
	Object.keys(allLibs.css).forEach((lib) => {
P
Paweł Kuna 已提交
464 465
		files.push(Array.isArray(allLibs.css[lib]) ? allLibs.css[lib] : [allLibs.css[lib]])
	})
C
codecalm 已提交
466

C
codecalm 已提交
467 468 469 470
  Object.keys(allLibs['js-copy']).forEach((lib) => {
	 files.push(allLibs['js-copy'][lib])
  })

P
Paweł Kuna 已提交
471
	files = files.flat()
C
codecalm 已提交
472

C
codecalm 已提交
473 474
	files.forEach((file) => {
		if (!file.match(/^https?/)) {
P
Paweł Kuna 已提交
475
			let dirname = path.dirname(file).replace('@', '')
C
codecalm 已提交
476
			let cmd = `mkdir -p "${distDir}/libs/${dirname}" && cp -r node_modules/${dirname}/* ${distDir}/libs/${dirname}`
C
codecalm 已提交
477 478 479

			cp.exec(cmd)
		}
P
Paweł Kuna 已提交
480
	})
C
codecalm 已提交
481

P
Paweł Kuna 已提交
482 483
	cb()
})
C
codecalm 已提交
484

C
codecalm 已提交
485 486 487
/**
 * Copy static files (flags, payments images, etc) to dist directory
 */
C
codecalm 已提交
488
gulp.task('copy-images', () => {
C
codecalm 已提交
489 490
	return gulp
		.src(`${srcDir}/img/**/*`)
P
Paweł Kuna 已提交
491 492
		.pipe(gulp.dest(`${distDir}/img`))
})
C
codecalm 已提交
493

C
codecalm 已提交
494 495 496
/**
 * Copy static files (demo images, etc) to demo directory
 */
C
codecalm 已提交
497
gulp.task('copy-static', () => {
C
codecalm 已提交
498 499
	return gulp
		.src(`${srcDir}/static/**/*`)
P
Paweł Kuna 已提交
500 501
		.pipe(gulp.dest(`${demoDir}/static`))
})
C
codecalm 已提交
502

C
codecalm 已提交
503 504 505
/**
 * Copy Tabler dist files to demo directory
 */
C
codecalm 已提交
506
gulp.task('copy-dist', () => {
C
codecalm 已提交
507 508
	return gulp
		.src(`${distDir}/**/*`)
P
Paweł Kuna 已提交
509 510
		.pipe(gulp.dest(`${demoDir}/dist/`))
})
C
codecalm 已提交
511

C
codecalm 已提交
512 513 514
/**
 * Add banner to build JS and CSS files
 */
C
codecalm 已提交
515 516 517 518
gulp.task('add-banner', () => {
	return gulp.src(`${distDir}/{css,js}/**/*.{js,css}`)
		.pipe(header(getBanner()))
		.pipe(gulp.dest(`${distDir}`))
P
Paweł Kuna 已提交
519
})
C
codecalm 已提交
520

P
Paweł Kuna 已提交
521
gulp.task('clean', gulp.series('clean-dirs', 'clean-jekyll'))
C
codecalm 已提交
522

523
gulp.task('start', gulp.series('clean', 'sass', 'js', gulp.parallel('js-demo', 'js-demo-theme'), 'mjs', 'build-jekyll', gulp.parallel('watch-jekyll', 'watch', 'browser-sync')))
C
codecalm 已提交
524

525
gulp.task('build-core', gulp.series('build-on', 'clean', 'sass', 'css-rtl', 'css-minify', 'js', gulp.parallel('js-demo', 'js-demo-theme'), 'mjs', 'copy-images', 'copy-libs', 'add-banner'))
P
Paweł Kuna 已提交
526 527
gulp.task('build-demo', gulp.series('build-on', 'build-jekyll', 'copy-static', 'copy-dist', 'build-cleanup', 'build-purgecss'/*, 'build-critical'*/))
gulp.task('build', gulp.series('build-core', 'build-demo'))