Skip to content

Instantly share code, notes, and snippets.

@llcawc
Last active January 21, 2023 20:32
Show Gist options
  • Save llcawc/70e81d621537e63739d39aa799a39b0c to your computer and use it in GitHub Desktop.
Save llcawc/70e81d621537e63739d39aa799a39b0c to your computer and use it in GitHub Desktop.
Start samples gulp file
// gulpfile.js
// simple frontend template starter, created pasmurno by llcawc, https://github.com/llcawc
// import modules
import fs from 'node:fs'
import { env } from 'node:process'
import gulp from 'gulp'
const { src, dest, parallel, series, watch } = gulp
import browsersync from 'browser-sync'
import htmlmin from 'gulp-htmlmin'
import sassDark from 'sass'
import sassGulp from 'gulp-sass'
const sass = sassGulp(sassDark)
import purgecss from 'gulp-purgecss'
import postCss from 'gulp-postcss'
import cssnano from 'cssnano'
import autoprefixer from 'autoprefixer'
import { rollup } from 'rollup'
import { babel } from '@rollup/plugin-babel'
import json from '@rollup/plugin-json'
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import { minify } from "terser"
import gulpTerser from "gulp-terser"
import imagemin from 'gulp-imagemin'
import changed from 'gulp-changed'
import replace from 'gulp-replace'
import rename from 'gulp-rename'
import { deleteAsync as del } from 'del'
// variables & path
const baseDir = './src' // Base directory path without «/» at the end
const distDir = './dist' // Distribution folder for uploading to the site
const fileswatch = 'html,htm,css,php,txt,js,cjs,mjs,webp,jpg,png,svg,json,md,woff2'
let paths = {
base: baseDir,
scripts: {
src: baseDir + '/assets/scripts/main.js',
dest: distDir + '/assets/js/main.min.js',
},
images: {
src: baseDir + '/assets/images/**/*.{png,jpg,svg}',
dest: distDir,
},
copy: {
src: baseDir + '/assets/fonts/*.*',
dest: distDir,
},
bi: {
src: 'node_modules/bootstrap-icons/font/fonts/**/*',
dest: distDir + '/assets/fonts/bootstrap-icons',
},
styles: {
src: [
baseDir + '/assets/sass/main.*',
// baseDir + '/assets/sass/fonts.*',
],
dest: distDir + '/assets/css',
reject: baseDir + '/assets/css',
},
purge: {
content: [
baseDir + '/**/*.html',
baseDir + '/assets/scripts/**/*.js',
// 'node_modules/bootstrap/js/dist/dom/*.js',
// 'node_modules/bootstrap/js/dist/{base-component,button}.js',
],
// css: [],
// safelist: {
// standart: ["selectorname"],
// deep: [/scrolltotop$/],
// greedy: [/on$/, /down$/, /is-hidden$/],
// },
keyframes: true,
},
}
// server reload task
function browserSync() {
browsersync.init({
server: { baseDir: distDir },
online: true,
notify: false,
open: false,
callbacks: {
ready: function(err, bs) {
// adding a middleware of the stack after Browsersync is running
bs.addMiddleware("*", function (req, res) {
res.writeHead(302, { location: "/404.html" })
res.end("Redirecting!")
})
}
},
})
}
// html task
function html() {
if (env.BUILD === 'production') {
return src(baseDir + '/*.html', { base: paths.base })
.pipe(htmlmin({ removeComments: true, collapseWhitespace: true }))
.pipe(dest(distDir + '/'))
} else {
return src(baseDir + '/*.html', { base: baseDir }).pipe(dest(distDir + '/'))
}
}
// scripts task
async function scripts() {
const bundle = await rollup({
input: paths.scripts.src,
plugins: [resolve(), commonjs({ include: 'node_modules/**' }), babel({ babelHelpers: 'bundled' }), json()],
})
await bundle.write({
file: paths.scripts.dest,
format: 'iife',
name: 'main',
sourcemap: env.BUILD === 'production' ? false : true,
})
}
// minify scripts task
function min() {
return src(distDir + '/assets/js/main.min.js')
.pipe(gulpTerser({}, minify))
.pipe(dest(distDir + '/assets/js'))
}
// inline scripts
function inlinescripts () {
return src(distDir + '/*.html', { base: paths.base })
.pipe(replace(
/<script src="assets\/js\/main.min.js"><\/script>/, () => {
const script = fs.readFileSync(distDir + '/assets/js/main.min.js', 'utf8')
return '<script>' + script + '</script>'
}
))
.pipe(dest(distDir + '/'))
}
// styles task
function styles() {
if (env.BUILD === 'production') {
return src(paths.styles.src)
.pipe(sass.sync())
.pipe(purgecss(paths.purge))
.pipe(postCss([
autoprefixer(),
cssnano({ preset: ['default', { discardComments: { removeAll: true } }],}),
]))
.pipe(rename({suffix: '.min'}))
.pipe(dest(paths.styles.dest))
} else {
return src(paths.styles.src, { sourcemaps: true })
.pipe(sass.sync().on('error', sass.logError))
.pipe(rename({suffix: '.min'}))
.pipe(dest(paths.styles.dest, { sourcemaps: '.' }))
}
}
// inline styles
function inlinestyles() {
return src(distDir + '/*.html', { base: paths.base })
.pipe(replace(
/<link rel="stylesheet" href="assets\/css\/main.min.css">/, () => {
const style = fs.readFileSync(distDir + '/assets/css/main.min.css', 'utf8')
return '<style>' + style + '</style>'
}
))
.pipe(dest(distDir + '/'))
}
// task view rejected styles
function reject() {
paths.purge.rejected = true
return src(paths.styles.src)
.pipe(sass.sync())
.pipe(purgecss(paths.purge))
.pipe(rename({suffix: '.rejected'}))
.pipe(dest(paths.styles.reject))
}
// images task
function images() {
return src(paths.images.src, { base: paths.base })
.pipe(changed(paths.images.dest))
.pipe(imagemin({ verbose: 'true' }))
.pipe(dest(paths.images.dest))
}
// copy task
function assetscopy() {
return src(paths.copy.src, { base: paths.base }).pipe(dest(paths.copy.dest))
}
function bicopy() {
return src(paths.bi.src).pipe(dest(paths.bi.dest))
}
// prepare clean task
function preclean() {
return del([
distDir + '/**',
distDir + '/assets/**',
'!' + distDir + '/assets',
'!' + distDir + '/assets/images',
], { force: true })
}
// post clean task
function postclean() {
return del([
distDir + '/assets/css',
distDir + '/assets/js',
])
}
function watchDev() {
watch(`./${baseDir}/**/*.html`, { usePolling: true }, html)
watch(`./${baseDir}/assets/scripts/**/*.{js,mjs,cjs}`, { usePolling: true }, scripts)
watch(`./${baseDir}/assets/sass/**/*.{scss,sass,css}`, { usePolling: true }, styles)
watch(`./${baseDir}/assets/images/**/*.{jpg,png,svg}`, { usePolling: true }, images)
watch(`./${distDir}/**/*.{${fileswatch}}`, { usePolling: true }).on('change', browsersync.reload)
}
export { assetscopy, html, styles, reject, scripts }
export let assets = series(assetscopy, bicopy, html, styles, reject, scripts)
export let serve = parallel(browserSync, watchDev)
export let dev = series(preclean, images, assets, serve)
export let build = series(preclean, images, assets, inlinestyles, min, inlinescripts, postclean)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment