UNPKG

toms-gulp-config

Version:

Gulp config for projects used for compiling JS, SCSS, and optimising images.

154 lines (131 loc) 3.86 kB
import { src, dest, watch, series, parallel } from 'gulp'; import yargs from 'yargs'; import sass from 'gulp-dart-sass'; import cleanCss from 'gulp-clean-css'; import gulpif from 'gulp-if'; import postcss from 'gulp-postcss'; import sourcemaps from 'gulp-sourcemaps'; import autoprefixer from 'autoprefixer'; import imagemin from 'gulp-imagemin'; import del from 'del'; import babel from 'gulp-babel'; import terser from 'gulp-terser'; import fiber from 'fibers'; import path from 'path'; import fs from 'fs'; import merge from '@ianwalter/merge'; import browserslist from 'browserslist'; const PRODUCTION = yargs.argv.prod; const ROOT = process.env.INIT_CWD; const configFile = path.join(ROOT, 'gulp-config.json'); const configDirs = fs.existsSync(configFile) ? JSON.parse(fs.readFileSync(configFile)) : {}; const defaultDirs = JSON.parse(fs.readFileSync('gulp-config.json')); let dirs = merge(defaultDirs, configDirs); const generateDirectories = (object) => { for (let key in object) { if (typeof object[key] === 'object') { generateDirectories(object[key]); } else if (typeof object[key] === 'string') { if( object[key].charAt(0) === '!' ) { object[key] = '!' + path.join(ROOT, object[key].slice(1)); } else { object[key] = path.join(ROOT, object[key]); } } } } generateDirectories(dirs); const imageminConfig = [ imagemin.svgo({ plugins: [ { removeViewBox: false } ] }), imagemin.gifsicle(), imagemin.mozjpeg(), imagemin.optipng(), ]; const browserslistConfig = browserslist.loadConfig({ path: ROOT }) || ['defaults']; export const clean = () => { let cleanDirs = []; for (let assetType in dirs) { if (typeof dirs[assetType].delete !== 'undefined' && dirs[assetType].delete) { cleanDirs = cleanDirs.concat([ path.join(dirs[assetType].output, '**'), path.join('!', dirs[assetType].output) ]); } } return del(cleanDirs, {force: true}); }; export const styles = () => { if (!dirs.styles) { return Promise.resolve(false); } return src(dirs.styles.input, {allowEmpty: true}) .pipe(gulpif(!PRODUCTION, sourcemaps.init())) .pipe(sass({fiber: fiber, includePaths: [path.join(ROOT, 'node_modules')]}).on('error', sass.logError)) .pipe(postcss([ autoprefixer({overrideBrowserslist: browserslistConfig}) ])) .pipe(gulpif(PRODUCTION, cleanCss())) .pipe(gulpif(!PRODUCTION, sourcemaps.write('.'))) .pipe(dest(dirs.styles.output)); } export const images = () => { if (!dirs.images) { return Promise.resolve(false); } return src(dirs.images.input, {allowEmpty: true}) .pipe(gulpif(PRODUCTION, imagemin(imageminConfig))) .pipe(dest(dirs.images.output)); } export const copy = () => { if (!dirs.copy) { return Promise.resolve(false); } return src(dirs.copy.input, {allowEmpty: true}) .pipe(dest(dirs.copy.output)); } export const scripts = () => { if (!dirs.scripts) { return Promise.resolve(false); } return src(dirs.scripts.input, {allowEmpty: true}) .pipe(gulpif(!PRODUCTION, sourcemaps.init())) .pipe(babel({ presets: [ [ '@babel/env', { targets: browserslistConfig, } ] ] })) .pipe(terser()) .pipe(gulpif(!PRODUCTION, sourcemaps.write('.'))) .pipe(dest(dirs.scripts.output)); } export const icons = () => { if (!dirs.icons) { return Promise.resolve(false); } return src(dirs.icons.input, {allowEmpty: true}) .pipe(gulpif(PRODUCTION, imagemin(imageminConfig))) .pipe(dest(dirs.icons.output)); } export const watchChanges = () => { [styles, images, copy, scripts, icons].forEach(task => { if (!dirs[task.name]) { return; } watch(dirs[task.name].watch, task); }); return Promise.resolve(false); } export const dev = series(clean, parallel(styles, images, copy, scripts, icons), watchChanges); export const build = series(clean, parallel(styles, images, copy, scripts, icons)); export default dev;