Skip to content

Instantly share code, notes, and snippets.

@thisanimus
Last active May 27, 2021 20:31
Show Gist options
  • Save thisanimus/8697beb1ef8c223312314077c4a0e4ae to your computer and use it in GitHub Desktop.
Save thisanimus/8697beb1ef8c223312314077c4a0e4ae to your computer and use it in GitHub Desktop.
Big Gulp
{
"script": {
"main": "src/js/script.js",
"es5": "assets/js/script.js",
"es6": "assets/js/script-esm.js",
"deps": "src/js/dependencies/**/*.js",
"modules": "src/js/modules/**/*.js",
"dest": "assets/js/"
},
"style": {
"main": "src/scss/style.scss",
"src": "src/**/*.{scss,sass}",
"dest": "assets/css/"
},
"images":{
"src":"src/img/*",
"dest":"assets/img/",
"sizes": [
{"width": 200, "quality": 90, "dir": "xs"},
{"width": 400, "quality": 80, "dir": "sm"},
{"width": 600, "quality": 80, "dir": "md"},
{"width": 1200, "quality": 70, "dir": "lg"},
{"width": 1400, "quality": 70, "dir": "xl"}
]
},
"markup": {
"templates": "**/*.html"
},
"server": {
"proxy": "https://domain.local",
"host": "domain.local"
},
"sftp": {
"host": "yourdomain.com",
"user": "yourSshUsername",
"pass": "",
"port": 22,
"src": [ "./**/*", "!node_modules/**/*", "!package-lock.json" ],
"remotePath": "/path/to/your/web/root"
}
}
// Requires Gulp v4.
const { src, dest, watch, series, parallel } = require('gulp');
// CSS Tools
const sass = require('gulp-sass');
const cleancss = require('gulp-clean-css');
const autoprefixer = require('gulp-autoprefixer');
// Image Tools
const imageResize = require('gulp-image-resize');
const imagemin = require('gulp-imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
// JS Tools
const rollup = require('rollup');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const { babel } = require('@rollup/plugin-babel');
// Build Tools
const browsersync = require('browser-sync').create();
const concat = require('gulp-concat');
const terser = require('gulp-terser');
const rename = require('gulp-rename');
// SFTP
var sftp = require('gulp-sftp-up4');
// Config
const config = require('./gulp-config');
// Minify SASS
function sassMinify() {
return src(config.style.dest + '/style.css')
.pipe(cleancss()) // minify it
.pipe(rename({ suffix: '-min' })) // rename it
.pipe(dest(config.style.dest))
.pipe(browsersync.stream()); // change the browser styles with no page reload
}
function sassCompile() {
return src(config.style.main)
.pipe(sass())
.on('error', function (err) {
console.log(err.formatted.toString());
this.emit('end');
})
.pipe(
// Add browser prefixes
autoprefixer({
overrideBrowserslist: ['> 1%', 'last 2 versions', 'ie >= 11'],
})
)
.pipe(dest(config.style.dest))
.pipe(browsersync.stream())
.on('end', () => {
sassMinify();
});
}
function processImages() {
let stream;
config.images.sizes.forEach((size) => {
stream = src(config.images.src)
// resize the image
.pipe(imageResize({ width: size.width }))
// compress the image
.pipe(
imagemin(
[
imageminMozjpeg({
quality: size.quality,
}),
],
{
verbose: true,
}
)
)
// send it to the right destination
.pipe(dest(config.images.dest + '/' + size.dir));
});
return stream;
}
// Get all the code we've imported into our main script file
// Roll all those exported classes up into a single file
function jsRollup() {
return rollup
.rollup({
input: config.script.main,
plugins: [nodeResolve()],
})
.then((bundle) => {
writeFile(bundle, 'es', config.script.es6);
});
}
// Transiple the other output file to something
// old browsers can understand
function jsTranspile() {
return rollup
.rollup({
input: config.script.main,
plugins: [
nodeResolve(),
babel({
presets: [['@babel/env', { modules: false }]],
sourceMaps: true,
babelHelpers: 'bundled',
exclude: 'node_modules/**',
}),
],
})
.then((bundle) => {
writeFile(bundle, 'iife', config.script.es5);
});
}
function writeFile(bundle, format, file) {
return bundle.write({
file: file,
format,
name: 'script',
});
}
// Concat any code that from the dependencies folder before the
// rest of the code. This is useful for old scripts that are not
// available in module form.
function jsConcatES6() {
return src([config.script.deps, config.script.es6]).pipe(concat('script-esm.js')).pipe(dest(config.script.dest));
}
function jsConcatES5() {
return src([config.script.deps, config.script.es5]).pipe(concat('script.js')).pipe(dest(config.script.dest));
}
// Create minified versions of our JS for prod
function jsMinify() {
return src([config.script.es5, config.script.es6])
.pipe(terser({ output: { comments: false } })) // Minify the JS
.pipe(rename({ suffix: '-min' })) // Rename it
.pipe(dest(config.script.dest)) // Write it to the output folder
.pipe(browsersync.stream());
}
function reload(done) {
browsersync.reload();
done();
}
// Watch all the build files, refresh code live in the browser,
// If the markup changes, reload the browser
function watchFiles() {
browsersync.init({
proxy: config.server.proxy,
host: config.server.host,
//server: {
// baseDir: './',
//},
open: 'external',
reloadOnRestart: true,
});
// Watch the Templates
// Force reload on change
watch(config.markup.templates, reload);
// Watch the Style
// Don't force style reload because we're
// streaming changes to browsersync
watch([config.style.src, config.style.main], { events: 'all', ignoreInitial: false }, series(sassCompile));
// Watch the JS
// Don't force style reload because we're
// streaming changes to browsersync
watch([config.script.modules, config.script.deps, config.script.main], series(jsRollup, jsTranspile, jsConcatES6, jsConcatES5, jsMinify));
}
exports.watch = watchFiles;
exports.images = series(processImages);
// Buid all the code from source
exports.build = series(jsRollup, jsTranspile, jsConcatES6, jsConcatES5, jsMinify, sassCompile, processImages);
// Push the code to a server via SFTP
exports.sftp = () => {
return src(config.sftp.src).pipe(
sftp({
host: config.sftp.host,
user: config.sftp.user,
pass: config.sftp.pass,
port: config.sftp.port,
remotePath: config.sftp.remotePath,
})
);
};
{
"name": "big-gulp",
"version": "1.0.0",
"description": "A taskrunner for building websites.",
"main": "index.php",
"keywords": [
"scss",
"css",
"framework",
"design-system",
"html",
"front-end",
"buttons",
"colors",
"forms",
"grid",
"mixins",
"spacing",
"typography"
],
"scripts": {
"gulp": "gulp",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Andrew Hale <hale.adh@gmail.com>",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.2",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"browser-sync": "^2.26.14",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^7.0.1",
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-image-resize": "^0.13.1",
"gulp-imagemin": "^7.1.0",
"gulp-rename": "^2.0.0",
"gulp-sass": "^4.1.0",
"gulp-sftp-up4": "^0.1.8",
"gulp-terser": "^2.0.1",
"imagemin-mozjpeg": "^9.0.0",
"node-sass": "^6.0.0",
"rollup": "^2.50.0"
},
"homepage": "https://andrewhale.design",
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment