Skip to content

Instantly share code, notes, and snippets.

@yarastqt
Created August 21, 2023 11:51
Show Gist options
  • Save yarastqt/c8d2c8583321056924cc9cca9115e7e9 to your computer and use it in GitHub Desktop.
Save yarastqt/c8d2c8583321056924cc9cca9115e7e9 to your computer and use it in GitHub Desktop.
import { resolve } from 'path'
import sequence from 'run-sequence'
import dotenv from 'dotenv'
import sort from 'sort-stream'
/* Common */
import gulp, { src, dest } from 'gulp'
import changed from 'gulp-changed'
import when from 'gulp-if'
import sourcemaps from 'gulp-sourcemaps'
import plumber from 'gulp-plumber'
import notify from 'gulp-notify'
import prettify from 'gulp-jsbeautifier'
import clean from 'gulp-clean'
import hash from 'gulp-hash-filename'
/* Server */
import { create as createServer } from 'browser-sync'
/* HTML */
import twig from 'gulp-twig'
import postHTML from 'gulp-posthtml'
import attrsSorter from 'posthtml-attrs-sorter'
import htmlLint from 'gulp-htmllint'
import inject from 'gulp-inject'
/* Styles */
import sass from 'gulp-sass'
import sassGlob from 'gulp-sass-glob'
import csso from 'gulp-csso'
import postcss from 'gulp-postcss'
import autoprefixer from 'autoprefixer'
import inlineSVG from 'postcss-inline-svg'
import mqpacker from 'css-mqpacker'
/* Images */
import imagemin from 'gulp-tinypng'
import svgo from 'gulp-svgo'
/* Scripts */
import webpack from 'webpack'
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import config from './config'
import webpackDevConfig from '../webpack/development.config'
import webpackProdConfig from '../webpack/production.config'
dotenv.config({
path: resolve(__dirname, '..', '.env'),
})
const server = createServer()
const bundler = webpack(webpackDevConfig)
const PROD = process.env.NODE_ENV === 'production'
function handleError(error) {
notify({
title: 'Compile error!',
message: '<%= error.message %>',
}).write(error)
}
/**
* Create dev server
*/
gulp.task('server', () => {
server.init({
open: false,
logFileChanges: false,
port: 8080,
server: {
baseDir: resolve(__dirname, '..', 'build'),
},
middleware: [
webpackDevMiddleware(bundler),
webpackHotMiddleware(bundler),
],
})
})
/**
* Compile twig templates
*/
gulp.task('templates', ['lint:html'], () => (
src(config.templates.src)
.pipe(plumber({
errorHandler: handleError,
}))
.pipe(twig({
base: resolve(__dirname, '..', 'src', 'blocks'),
}))
.pipe(dest(config.templates.dist))
.pipe(server.stream())
))
/**
* Inject css and js files at production mode
*/
gulp.task('inject', () => (
src(config.inject.src)
.pipe(inject(
src(config.inject.injectable, { read: false })
.pipe(sort((a, b) => 1)),
{ removeTags: true, ignorePath: '../build' }
))
.pipe(dest(config.templates.dist))
))
/**
* Prettify HTML
* sorting attributes, normalize indents
*/
gulp.task('prettify:html', ['templates'], () => (
src(config.templates.prettify)
.pipe(postHTML([
attrsSorter({
order: [
'id', 'class', 'name', 'data-*', 'src', 'for',
'rel', 'href', 'type', 'media', 'value', 'title',
'alt', 'role', 'aria-*',
],
}),
]))
.pipe(prettify({
indent_size: 2,
unformatted: ['code', 'pre', 'br'],
extra_liners: [],
}))
.pipe(dest(config.templates.dist))
))
/**
* HTML Linting
*/
gulp.task('lint:html', () => (
src(config.templates.watch)
.pipe(htmlLint({
config: resolve(__dirname, '..', '.htmllintrc'),
}))
))
/**
* Compile sass and run postcss, csso
*/
gulp.task('styles', () => (
src(config.styles.src)
.pipe(plumber({
errorHandler: handleError,
}))
.pipe(when(!PROD, sourcemaps.init()))
.pipe(sassGlob())
.pipe(sass())
.pipe(postcss([
mqpacker(),
autoprefixer({
browsers: ['last 2 versions'],
}),
inlineSVG({
path: resolve(__dirname, '..', 'src', 'common', 'i', 'svg'),
}),
]))
.pipe(when(PROD, csso()))
.pipe(when(PROD, hash({
format: '{name}.min.{hash:10}{ext}',
})))
.pipe(when(!PROD, sourcemaps.write()))
.pipe(dest(config.styles.dist))
.pipe(when(!PROD, server.stream()))
))
/**
* Building javascript by webpack
*/
gulp.task('scripts', (callback) => {
webpack(webpackProdConfig, callback)
})
/**
* Images tasks
* Optimize SVG and Pictures at production mode
*/
gulp.task('images', ['pictures', 'svg'])
/**
* Optimize svg by SVGO
*/
gulp.task('svg', () => (
src(config.svg.src, { base: config.svg.base })
.pipe(changed(config.svg.dist))
.pipe(when(PROD, svgo()))
.pipe(dest(config.svg.dist))
))
/**
* Optimize jpg, jpeg, png by tinyPNG
*/
gulp.task('pictures', () => (
src(config.pictures.src)
.pipe(changed(config.pictures.dist))
.pipe(when(PROD, imagemin(process.env.TINYPNG_API_KEY)))
.pipe(dest(config.pictures.dist))
))
/**
* Copy PWA manifest
*/
gulp.task('copy-manifest', () => (
src(config.manifest.src)
.pipe(dest(config.manifest.dist))
))
/**
* Remove build folder
*/
gulp.task('clean', () => (
src(config.build, { read: false })
.pipe(clean({ force: true }))
))
/**
* Building project with development mode
*/
gulp.task('build:dev', () => {
sequence('clean', [
'templates',
'styles',
'images',
'copy-manifest',
])
})
/**
* Building project with production mode
*/
gulp.task('build:prod', () => {
sequence('clean', [
'prettify:html',
'styles',
'images',
'scripts',
'copy-manifest',
], 'inject')
})
/**
* Watchers
*/
gulp.task('watch', () => {
gulp.watch(config.templates.watch, ['templates'])
gulp.watch(config.styles.watch, ['styles'])
gulp.watch(config.manifest.watch, ['copy-manifest'])
gulp.watch(config.pictures.watch, ['pictures'])
gulp.watch(config.svg.watch, ['svg'])
gulp.watch(config.scripts.watch).on('change', server.reload)
})
/**
* Gulp run this task as default
*/
gulp.task('default', [
'build:dev',
'server',
'watch',
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment