templates/webpunk-templates/gulpfile.old.mjs
2025-06-15 00:02:46 +03:00

258 lines
6.5 KiB
JavaScript

import autoprefixer from 'autoprefixer'
import concat from 'gulp-concat'
import csso from 'gulp-csso'
import { deleteAsync } from 'del'
import gulp from 'gulp'
import gulpWebp from 'gulp-webp'
import imagemin, { mozjpeg, optipng, svgo } from 'gulp-imagemin'
import imageminAvif from 'imagemin-avif'
import order from 'gulp-order'
import plumber from 'gulp-plumber'
import postcss from 'gulp-postcss'
import pug from 'gulp-pug'
import rename from 'gulp-rename'
import uglify from 'gulp-uglify-es'
import * as dartSass from 'sass'
import gulpSass from 'gulp-sass'
import sourcemap from 'gulp-sourcemaps'
import svgstore from 'gulp-svgstore'
import sync from 'browser-sync'
import { nanoid } from 'nanoid'
import postcssUrl from 'postcss-url'
import inject from 'gulp-inject'
import newer from 'gulp-newer' // Added gulp-newer
const baseUrl = '.'
const pathCss = '..'
const searchId = Date.now()
const getImageSrcset = (path, format, params) => {
return [1, 2]
.map((dpr) => `${baseUrl}${path}@${dpr}x.${format}${params} ${dpr}x`)
.join(', ')
}
const getImageMime = (format) => {
switch (format) {
case 'avif':
return 'image/avif'
case 'webp':
return 'image/webp'
case 'jpeg':
case 'jpg':
return 'image/jpeg'
case 'png':
return 'image/png'
default:
return null
}
}
const sass = gulpSass(dartSass)
const clean = async () => {
return await deleteAsync(['dist'])
}
const copy = () => {
return gulp
.src(
[
'src/fonts/**/*.{woff,woff2}',
'src/img/**/*.{webm,webp,avif,jpg,jpeg,png,svg}',
'src/favicon/**/*',
'src/favicon.ico',
'src/settings.js',
'src/urls.json',
'src/robots.txt'
],
{ base: 'src', encoding: false }
)
.pipe(gulp.dest('dist'))
}
const css = () => {
return gulp
.src('src/scss/index.scss')
.pipe(plumber())
.pipe(sourcemap.init())
.pipe(sass.sync().on('error', sass.logError))
.pipe(
postcss([
postcssUrl({
url: (asset) => {
if (asset.url.startsWith('/')) {
return `${pathCss}${asset.url}?v=${searchId}`
}
return asset.url
}
}),
autoprefixer({ remove: false })
])
)
.pipe(rename('style.css'))
.pipe(sourcemap.write('.'))
.pipe(gulp.dest('dist/css'))
.pipe(sync.stream())
.pipe(csso())
.pipe(rename('style.min.css'))
.pipe(gulp.dest('dist/css'))
}
const images = () => {
return gulp
.src('src/img/**/*.{png,jpg,jpeg,svg}', { base: 'src', encoding: false }) // Process all images in subfolders, keep base for dest path
.pipe(newer('dist')) // Process only newer files, compare with base 'dist' (e.g. dist/img/...)
.pipe(
imagemin(
[
optipng({ optimizationLevel: 3 }),
mozjpeg({ quality: 80, progressive: true }), // Quality for JPEG
svgo({
plugins: [{ name: 'removeUnknownsAndDefaults', active: false }]
})
],
{ silent: true }
)
)
.pipe(gulp.dest('dist')) // Output to dist, maintaining folder structure from base
}
const webp = () => {
return gulp
.src('src/img/**/*.{png,jpg,jpeg}', { base: 'src', encoding: false }) // Process all images in subfolders
.pipe(newer({ dest: 'dist', ext: '.webp' })) // Process only newer, check against .webp extension in dist
.pipe(gulpWebp({ quality: 80 })) // Quality for WebP
.pipe(gulp.dest('dist')) // Output to dist, maintaining folder structure
}
const avif = () => {
return gulp
.src('src/img/**/*.{png,jpg,jpeg}', { base: 'src', encoding: false }) // Process all images in subfolders
.pipe(newer({ dest: 'dist', ext: '.avif' })) // Process only newer, check against .avif extension in dist
.pipe(imagemin([imageminAvif({ quality: 50 })], { silent: true })) // Quality for AVIF
.pipe(rename((path) => (path.extname = '.avif')))
.pipe(gulp.dest('dist')) // Output to dist, maintaining folder structure
}
const processImages = gulp.parallel(images, webp, avif)
const sprite = () => {
return gulp
.src('src/icons/**/*.svg')
.pipe(svgstore({ inlineSvg: true }))
.pipe(rename(`sprite.svg`))
.pipe(gulp.dest('dist/img'))
}
const injectSprite = () => {
const spritePath = 'dist/img/sprite.svg'
return gulp
.src('dist/*.html')
.pipe(
inject(gulp.src(spritePath), {
transform: (_, file) => {
return file.contents.toString()
}
})
)
.pipe(gulp.dest('dist'))
}
const jsCommon = () => {
return gulp
.src('src/js/common/*.js')
.pipe(
plumber({
errorHandler(err) {
console.error(err.toString())
this.emit('end')
}
})
)
.pipe(order(['_utils.js', '*.js']))
.pipe(concat(`script.js`))
.pipe(gulp.dest('dist/js'))
.pipe(uglify.default())
.pipe(rename(`script.min.js`))
.pipe(gulp.dest('dist/js'))
}
const jsVendor = () => {
return gulp
.src('src/js/vendor/*.js')
.pipe(
plumber({
errorHandler(err) {
console.error(err.toString())
this.emit('end')
}
})
)
.pipe(concat(`vendor.js`))
.pipe(gulp.dest('dist/js'))
.pipe(uglify.default())
.pipe(rename(`script.min.js`))
.pipe(gulp.dest('dist/js'))
}
const html = () => {
return gulp
.src('src/pug/pages/**/*.pug')
.pipe(plumber())
.pipe(
pug({
pretty: true,
basedir: 'src/pug',
locals: {
baseUrl,
searchId,
getSrcset: getImageSrcset,
getMime: getImageMime
}
})
)
.pipe(gulp.dest('dist'))
}
const refresh = (done) => {
sync.reload()
done()
}
const server = () => {
sync.init({
server: 'dist/',
notify: false,
open: false,
cors: true,
ui: false
})
gulp.watch('src/pug/**/*.{pug,js}', gulp.series(html, injectSprite, refresh))
gulp.watch(
'src/icons/**/*.svg',
gulp.series(sprite, html, injectSprite, refresh)
)
gulp.watch('src/scss/**/*.scss', gulp.series(css))
gulp.watch('src/js/**/*.js', gulp.series(jsVendor, jsCommon, refresh))
// Watch for source image changes and run all image processing tasks.
// gulp-newer within each task will ensure only necessary files are processed.
gulp.watch('src/img/**/*.{png,jpg,jpeg,svg}', gulp.series(processImages, refresh))
}
export const build = gulp.series(
clean,
copy,
css,
jsVendor,
jsCommon,
processImages,
sprite,
html,
injectSprite
)
export const dev = gulp.series(build, server)