|
/* eslint-env node, es6 */ |
|
/* global require */ |
|
'use strict'; |
|
|
|
/** |
|
* Configuration |
|
*/ |
|
|
|
// Load dependencies |
|
const {parallel, series, src, dest, task, watch,} = require('gulp'), |
|
gulpIf = require('gulp-if'), |
|
sourceMaps = require('gulp-sourcemaps'), |
|
sass = require('gulp-sass'), |
|
sassGlobbing = require('gulp-sass-globbing'), |
|
sassLint = require('gulp-sass-lint'), |
|
postCss = require('gulp-postcss'), |
|
autoprefixer = require('autoprefixer'), |
|
cssNano = require('cssnano'), |
|
pxToRem = require('postcss-pxtorem'), |
|
babel = require('gulp-babel'), |
|
uglify = require('gulp-uglify'), |
|
eslint = require('gulp-eslint'); |
|
|
|
// File locations |
|
const cssSource = './scss/**/*.scss', |
|
cssOutput = './css/', |
|
jsSource = './js/**/*.es6', |
|
jsOutput = './js/compiled/'; |
|
|
|
// Create easier to read errors |
|
const logError = (error) => console.log( |
|
`\n- Begin error ----------\n |
|
${error} |
|
\n- End error ------------\n` |
|
); |
|
|
|
const isDev = process.env.NODE_ENV === 'dev'; |
|
|
|
if (isDev) { |
|
console.log('/************************\n * Compiling in DEV mode!\n */\n'); |
|
} |
|
else { |
|
console.log('/*************************\n * Compiling in PROD mode.\n */\n'); |
|
} |
|
|
|
|
|
/** |
|
* Sass Globbing |
|
*/ |
|
const globScssFolder = (folderName) => |
|
// Only glob partials |
|
src(`scss/${folderName}/**/_*.scss`) |
|
.pipe( |
|
sassGlobbing( |
|
{'path': `_${folderName}.scss`,}, |
|
{ |
|
'useSingleQuotes': true, |
|
'signature': '// Generated with gulp-sass-globbing', |
|
} |
|
) |
|
) |
|
.pipe(dest('scss')); |
|
|
|
// Flatten output so Gulp doesn't poop it's pants |
|
// !! Any additions to this should be added to watch exclusions, |
|
// !! otherwise there's an infinite compile loop |
|
const globComponentScss = () => globScssFolder('component'); |
|
const globLayoutScss = () => globScssFolder('layout'); |
|
const globSkinScss = () => globScssFolder('skin'); |
|
|
|
const globScss = parallel(globComponentScss, globLayoutScss, globSkinScss); |
|
|
|
/** |
|
* CSS Compilation |
|
*/ |
|
const processScss = () => |
|
src(cssSource) |
|
// Lint first |
|
.pipe(sassLint()) |
|
.pipe(sassLint.format()) |
|
.pipe(sassLint.failOnError()) |
|
// Start compiling |
|
.pipe(gulpIf(isDev, sourceMaps.init())) |
|
.pipe(sass()) |
|
.pipe( |
|
postCss([ |
|
pxToRem({ |
|
'propList': ['*',], |
|
}), |
|
autoprefixer({ |
|
'browsers': '> 0.25%, last 2 versions, Firefox ESR, not dead', |
|
}), |
|
]) |
|
) |
|
// Minify if production build |
|
.pipe(gulpIf(!isDev, postCss([cssNano(),]))) |
|
.pipe(gulpIf(isDev, sourceMaps.write())) |
|
.pipe(dest(cssOutput)); |
|
|
|
const compileCSS = series(globScss, processScss); |
|
|
|
/** |
|
* JS Compilation |
|
*/ |
|
const compileJavascript = () => |
|
src(jsSource) |
|
.pipe(gulpIf(isDev, sourceMaps.init())) |
|
.pipe(eslint()) |
|
.pipe(eslint.format()) |
|
.pipe(eslint.failAfterError()) |
|
.pipe( |
|
babel({ |
|
'presets': ['@babel/preset-env',], |
|
}) |
|
// Provide meaningful error output |
|
.on('error', (error) => logError(error)) |
|
) |
|
// Minify if production build |
|
.pipe(gulpIf(!isDev, uglify())) |
|
.pipe(gulpIf(isDev, sourceMaps.write())) |
|
.pipe(dest(jsOutput)); |
|
|
|
/** |
|
* Watch Files |
|
*/ |
|
const watchFiles = () => { |
|
watch( |
|
[ |
|
cssSource, |
|
// Exclude the auto-generated files to prevent an infinite compile loop |
|
'!scss/_component.scss', |
|
'!scss/_layout.scss', |
|
'!scss/_skin.scss', |
|
], |
|
compileCSS |
|
); |
|
watch(jsSource, compileJavascript); |
|
}; |
|
|
|
task('default', parallel(compileCSS, compileJavascript)); |
|
task('watch', watchFiles); |