Last active
January 19, 2019 03:14
-
-
Save mherchel/49a5d4e3beb30d777c38f8db6ed6fd4a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-env node, es6 */ | |
/* global require */ | |
'use strict'; | |
/** | |
* Configuration | |
*/ | |
// Load dependencies | |
const { parallel, series, src, dest, task, watch, } = require('gulp'); | |
const fs = require('fs'); | |
const path = require('path'); | |
const gulpIf = require('gulp-if'); | |
const sourceMaps = require('gulp-sourcemaps'); | |
const sass = require('gulp-sass'); | |
const sassGlobbing = require('gulp-sass-globbing'); | |
const sassLint = require('gulp-sass-lint'); | |
const postCss = require('gulp-postcss'); | |
const autoprefixer = require('autoprefixer'); | |
const cssNano = require('cssnano'); | |
const pxToRem = require('postcss-pxtorem'); | |
const babel = require('gulp-babel'); | |
const uglify = require('gulp-uglify'); | |
const eslint = require('gulp-eslint'); | |
const rename = require('gulp-rename'); | |
const del = require('del'); | |
// File locations | |
const cssSource = './scss/**/*.scss'; | |
const cssOutput = './css/'; | |
const jsSource = './js/src/*.es6'; | |
const jsOutput = './js/compiled/'; | |
// @see https://github.com/gulpjs/gulp/blob/master/docs/recipes/running-task-steps-per-folder.md | |
function getFolders(dir) { | |
return fs.readdirSync(dir) | |
.filter(function (file) { | |
return fs.statSync(path.join(dir, file)).isDirectory(); | |
}); | |
} | |
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 | |
*/ | |
// Will be used to ignore globbed files later | |
let globbedScssFiles = []; | |
/** | |
* Helper to create proper globbing config | |
* | |
* @param {string} folderName Name of folder to glob | |
* @param {string} fileName Optional, if not provided, will create a partial | |
* with an underscore followed by the filename of the folder | |
*/ | |
const globScssFolder = (folderName, fileName) => { | |
// If no filename is given default to scss dir and prepend underscore | |
if (typeof fileName !== 'string') { | |
fileName = `${folderName}.glob.scss`; | |
} | |
// Adds partial to globbedScssFiles, which then gets excluded from being watched. | |
if (Object.values(globbedScssFiles).indexOf(`scss/${fileName}`) === -1) { | |
globbedScssFiles.push(`scss/${fileName}`); | |
} | |
// Guarantees that functions, mixins, variables will be available to Sass partial. | |
const globSignature = '@import \'global_include\';'; | |
return src(`scss/${folderName}/**/_*.scss`) | |
.pipe( | |
sassGlobbing( | |
{ | |
'path': fileName, | |
}, | |
{ | |
'useSingleQuotes': true, | |
'signature': globSignature, | |
} | |
) | |
) | |
.pipe(dest('scss')); | |
}; | |
// This is the array that holds static list of directories to glob. | |
const sassGlobs = [ | |
() => globScssFolder('base'), | |
() => globScssFolder('utility'), | |
() => globScssFolder('layout'), | |
]; | |
// Loop through component subdirectories, and create a SCSS file for each directory. | |
// @todo This only happens when you start Gulp, so if you create a new directory, you need to | |
// stop / start the process. | |
const folders = getFolders('scss/component'); | |
const componentGlobs = folders.map(function(folder) { | |
return () => globScssFolder('component/' + folder, 'component/' + folder + '.glob.scss'); | |
}); | |
// Add component globs into the sassGlobs array. | |
sassGlobs.push(componentGlobs); | |
const globScss = parallel(...sassGlobs); | |
// Delete any *.glob.scss files that are autogenerated. | |
const deleteGlobFiles = () => del('scss/**/*.glob.scss'); | |
const processScss = () => | |
src(cssSource) | |
// Lint first | |
.pipe(sassLint()) | |
.pipe(sassLint.format()) | |
// Uncomment the next line to fail when Scss is invalid. | |
// .pipe(sassLint.failOnError()) | |
// Start compiling | |
.pipe(gulpIf(isDev, sourceMaps.init())) | |
.pipe(sass({ | |
includePaths: ['scss'] | |
})) | |
// By default, the CSS files have a .glob.css extention. Replace this with .css. | |
.pipe(rename( | |
path => path.basename = path.basename.replace('.glob', '') | |
)) | |
.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, deleteGlobFiles); | |
/** | |
* 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 = (done) => { | |
// Prepend globbedFiles with ! so they aren't watched causing an infinite loop, | |
// then add the source files to the beginning of the array | |
const watchedScss = globbedScssFiles.map(file => `!${file}`); | |
watchedScss.unshift(cssSource); | |
// Do what we came here to do | |
watch(watchedScss, compileCSS); | |
watch(jsSource, compileJavascript); | |
done(); | |
}; | |
task('default', parallel(compileCSS, compileJavascript)); | |
task('watch', series(globScss, watchFiles)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "bitcrusher", | |
"version": "0.1.0", | |
"license": "GPLv2", | |
"engines": { | |
"node": ">=8.x.x" | |
}, | |
"devDependencies": { | |
"@babel/core": "^7.2.2", | |
"@babel/preset-env": "^7.2.0", | |
"autoprefixer": "^9.4.2", | |
"cssnano": "^4.1.7", | |
"del": "^3.0.0", | |
"file-system": "^2.2.2", | |
"gulp": "^4.0.0", | |
"gulp-babel": "^8.0.0", | |
"gulp-eslint": "^5.0.0", | |
"gulp-if": "^2.0.2", | |
"gulp-postcss": "^8.0.0", | |
"gulp-rename": "^1.4.0", | |
"gulp-sass": "^4.0.2", | |
"gulp-sass-globbing": "0.0.2", | |
"gulp-sass-lint": "^1.4.0", | |
"gulp-sourcemaps": "^2.6.4", | |
"gulp-uglify": "^3.0.1", | |
"postcss-pxtorem": "^4.0.1" | |
}, | |
"scripts": { | |
"gulp": "gulp", | |
"build": "gulp", | |
"build:dev": "NODE_ENV=dev gulp", | |
"watch": "NODE_ENV=dev gulp watch", | |
"clean": "NODE_ENV=dev gulp clean", | |
"start": "npm run watch" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment