How I made my Gulp build for a fast, easy and enjoyable layout

Seriously and professionally, I started doing layout in 2019, although before that, even from school, I was interested in this topic as an amateur. Therefore, it's hard for me to call myself a beginner, but I'm not a professional with 5+ years of experience either. Nevertheless, I managed to get acquainted with the Gulp collector, its plugins and made for myself a good, as for me, assembly for work. I'll tell you about its capabilities today.





! . , , , .





?

  • ( head, header, footer , );





  • (SASS/SCSS);





  • ttf eot, woff, woff2;





  • ( ) ;





  • ( ) -;





  • " ";





  • html/css/js ;





  • php;





  • FTP;





  • .





, - .

https://github.com/budfy/Easy-webdev-startpack





( ). LTS- Node.js NPM ( Node.js) Yarn. , , NPM, , Yarn NPM-.





, - . ( , , ) npm init.







npm , , .... . .





Visual Studio Code ( ) + .





, Gulp. npm i gulp -global



- Gulp npm i gulp --save-dev



- Gulp . --save



( , ), -dev



, , . , Swiper, , -dev



, , .





, Gulp , gulpfile.js, .





Gulp , . require:





const gulp = require('gulp');
      
      



, . , , require-dir. ( , , , - npm i $PLUGIN-NAME$ --save-dev



). , ( tasks):





const gulp = require('gulp');

const requireDir = require('require-dir');
const tasks = requireDir('./tasks');
      
      



, . tasks hello.js. , "Hello Gulp!" ( - , ).





module.exports = function hello () {
	console.log("Hello Gulp!");
}
      
      



gulpfile.js hello:





const gulp = require('gulp');

const requireDir = require('require-dir');
const tasks = requireDir('./tasks');

exports.hello = tasks.hello;
      
      



gulp hello



. - :





[13:17:15] Using gulpfile D:\Web projects\Easy-webdev-startpack-new\gulpfile.js
[13:17:15] Starting 'hello'...
Hello Gulp!
[13:17:15] The following tasks did not complete: hello
[13:17:15] Did you forget to signal async completion?
      
      



, gulp --tasks



.





, , , . () /src /build .





src/ :
  • components/ -





  • components/bem-blocks/ - -





  • components/page-blocks/ - , , ..





  • fonts/ -





  • img/ -





  • js/ - JavaScript





  • scss/ -





  • scss/base/ - ,





  • svg/ - SVG





  • svg/css/ - SVG-, CSS





:





: , img/



, fonts/



.. ( Github) .gitkeep. , Github .





Gulp , . . , .






scss , scss css. , Gulp-sass, scss css, . , , scss- , gulp-sass-bulk-importer, - gulp-autoprefixer, css - gulp-clean-css ("" ) - gulp-concat. , , DevTools , , gulp-sourcemaps. npm i , , : npm i --save-dev gulp-sass gulp-sass-bulk-importer gulp-autoprefixer gulp-clean-css gulp-concat gulp-sourcemaps







tasks/ , , scss-. gulp src dest, :





const {
	src,
	dest
} = require('gulp');
const sass = require('gulp-sass');
const bulk = require('gulp-sass-bulk-importer');
const prefixer = require('gulp-autoprefixer');
const clean = require('gulp-clean-css');
const concat = require('gulp-concat');
const map = require('gulp-sourcemaps');
      
      



:





module.exports = function style({
	return
}
      
      



- scss . Gulp .pipe



, src



. , , , src/, , build/.





:





  1. scss scss/





  2. (sourcepams)





  3. css













  4. style.css









  5. build





(return) , . :





	return src('src/scss/**/*.scss')
		.pipe(map.init())
		.pipe(bulk())
		.pipe(sass())
		.pipe(prefixer())
		.pipe(clean())
		.pipe(concat('style.min.css'))
		.pipe(map.write('../sourcemaps/'))
		.pipe(dest('build/css/'))
      
      



src('src/scss/**/*.scss')



- (source)





.pipe(map.init())



- ,





.pipe(bulk())



- , @include scss ,





.pipe(sass())



- sass





.pipe(prefixer())



- ,





.pipe(clean())



- "" css





.pipe(concat('style.min.css'))



-





.pipe(map.write('../sourcemaps/'))



- ""





.pipe(dest('build/css/'))



-





, - . , . , : .pipe(sass({outputStyle: 'compressed'})



. sass css compressed, error , , ( ). :





.pipe(sass({
  outputStyle: 'compressed'
}).on('error', sass.logError))
      
      



. , - , .





.pipe(prefixer({
  overrideBrowserslist: ['last 8 versions'],
  browsers: [
    'Android >= 4',
    'Chrome >= 20',
    'Firefox >= 24',
    'Explorer >= 11',
    'iOS >= 6',
    'Opera >= 12',
    'Safari >= 6',
  ],
}))
      
      



: (level) 2 .





bs , .





, tasks/style.js :
const {
	src,
	dest
} = require('gulp');
const sass = require('gulp-sass');
const bulk = require('gulp-sass-bulk-importer');
const prefixer = require('gulp-autoprefixer');
const clean = require('gulp-clean-css');
const concat = require('gulp-concat');
const map = require('gulp-sourcemaps');
const bs = require('browser-sync');

module.exports = function style() {
	return src('src/scss/**/*.scss')
		.pipe(map.init())
		.pipe(bulk())
		.pipe(sass({
			outputStyle: 'compressed'
		}).on('error', sass.logError))
		.pipe(prefixer({
			overrideBrowserslist: ['last 8 versions'],
			browsers: [
				'Android >= 4',
				'Chrome >= 20',
				'Firefox >= 24',
				'Explorer >= 11',
				'iOS >= 6',
				'Opera >= 12',
				'Safari >= 6',
			],
		}))
		.pipe(clean({
			level: 2
		}))
		.pipe(concat('style.min.css'))
		.pipe(map.write('../sourcemaps/'))
		.pipe(dest('build/css/'))
    .pipe(bs.stream())
}
      
      



, . plugins, - node_modules const plugins = [];



. - . gulp.src gulp.dest, gulp-concat gulp-sourcemaps "":





  1. ( - )









  2. sass





  3. css ( )













  4. build/css





- , plugins - done()



, , . , . .





chalk , . , , :





, tasks/libs_style.js :
const plugins = [];

const {
	src,
	dest
} = require('gulp');
const sass = require('gulp-sass');
const concat = require('gulp-concat');
const map = require('gulp-sourcemaps');
const chalk = require('chalk');

module.exports = function libs_style(done) {
	if (plugins.length > 0) {
		return src(plugins)
			.pipe(map.init())
			.pipe(sass({
				outputStyle: 'compressed'
			}).on('error', sass.logError))
			.pipe(concat('libs.min.css'))
			.pipe(map.write('../sourcemaps/'))
			.pipe(dest('build/css/'))
	} else {
		return done(console.log(chalk.redBright('No added CSS/SCSS plugins')));
	}
}
      
      



JavaScript

C JavaScript . , . , babel, ES5, , (- ). , : JS-, / .





JS gulp-uglify-es - JS- gulp-babel . , .





, :





  1. (sources)





















  2. build/js/





() 4 babel . @babel/core , @babel/preset-env. , .babelrc



, Babel :





{
  "presets": ["@babel/preset-env"]
}
      
      



. , . build, .





tasks/dev_js.js
const {
	src,
	dest
} = require('gulp');
const uglify = require('gulp-uglify-es').default;
const concat = require('gulp-concat');
const map = require('gulp-sourcemaps');
const bs = require('browser-sync');

module.exports = function dev_js() {
	return src(['src/components/**/*.js', 'src/js/01_main.js'])
		.pipe(map.init())
		.pipe(uglify())
		.pipe(concat('main.min.js'))
		.pipe(map.write('../sourcemaps'))
		.pipe(dest('build/js/'))
    .pipe(bs.stream())
}
      
      



tasks/libs_js.js
const plugins = [];
const {
	src,
	dest
} = require('gulp');
const uglify = require('gulp-uglify-es').default;
const concat = require('gulp-concat');
const map = require('gulp-sourcemaps');
const chalk = require('chalk');

module.exports = function libs_js(done) {
	if (plugins.length > 0)
		return src(plugins)
			.pipe(map.init())
			.pipe(uglify())
			.pipe(concat('libs.min.js'))
			.pipe(map.write('../sourcemaps'))
			.pipe(dest('build/js/'))
	else {
		return done(console.log(chalk.redBright('No added JS plugins')));
	}
}
      
      



tasks/build__js.js
const {
	src,
	dest
} = require('gulp');
const uglify = require('gulp-uglify-es').default;
const babel = require('gulp-babel');
const concat = require('gulp-concat');

module.exports = function build_js() {
	return src(['src/components/**/*.js', 'src/js/01_main.js'])
		.pipe(uglify())
		.pipe(babel({
			presets: ['@babel/env']
		}))
		.pipe(concat('main.min.js'))
		.pipe(dest('build/js/'))
}
      
      



, src/js/01_main.js



, src/js



.





. -, , gulp-uglify-es () default: const uglify = require('gulp-uglify-es').default



- - . . - , . -, build- sourcemaps, . , .






HTML/PHP

HTML PHP, , . , Pug Nunjucks , Emmet HTML, : gulp-file-include, , , - . , , . PHP . require PHP . - Gulp , .





HTML gulp-htmlmin, .pipe(htmlmin({ collapseWhitespace: true }))



html. , , - 90% , . , .





gulp-file-include html:





tasks/html.js
const {
	src,
	dest
} = require('gulp');
const include = require('gulp-file-include');
const bs = require('browser-sync');

module.exports = function html() {
	return src(['src/**/*.html', '!!src/components/**/*.html'])
		.pipe(include())
		.pipe(dest('build'))
    .pipe(bs.stream())
}
      
      



. src , (!) . JavaScript "". html 'src/**/*.html'



, , '



!src/components/**/*.html'



src/components. , build , , , . .





php. , ., . .





tasks/php.js
const {
	src,
	dest
} = require('gulp');
const include = require('gulp-file-include');
const bs = require('browser-sync');

module.exports = function php() {
	return src('src/**/*.php')
		.pipe(include())
		.pipe(dest('build'))
    .pipe(bs.stream())
}
      
      



. svg, . :





  1. .





  2. webp.





  3. svg .





  4. svg CSS c svg ::after



    ::before







! , .





  • gulp-changed - . , .





  • gulp-multi-dest - .





  • gulp-imagemin -





  • imagemin-jpeg-recompress -





  • imagemin-pngquant -





  • gulp-webp - (png, jpeg) webp





  • gulp-svgmin - svg





  • gulp-svg-css-pseudo - svg css





  • gulp-svg-sprite - svg . , . .





: tasks/rastr.js



, tasks/webp.js



, tasks/svg_css.js



tasks/svg_sprite.js



. , , , . . Just belive me, , . :





tasks/rastr.js
const {
	src,
	dest
} = require('gulp');
const changed = require('gulp-changed');
const imagemin = require('gulp-imagemin');
const recompress = require('imagemin-jpeg-recompress');
const pngquant = require('imagemin-pngquant');
const bs = require('browser-sync');

module.exports = function rastr() {
	return src('src/img/**/*.+(png|jpg|jpeg|gif|svg|ico)')
		.pipe(changed('build/img'))
		.pipe(imagemin({
				interlaced: true,
				progressive: true,
				optimizationLevel: 5,
			},
			[
				recompress({
					loops: 6,
					min: 50,
					max: 90,
					quality: 'high',
					use: [pngquant({
						quality: [0.8, 1],
						strip: true,
						speed: 1
					})],
				}),
				imagemin.gifsicle(),
				imagemin.optipng(),
				imagemin.svgo()
			], ), )
		.pipe(dest('build/img'))
  	.pipe(bs.stream())
}
      
      



, : src('src/img/**/*.+(png|jpg|jpeg|gif|svg|ico)')



. ( |



) "". , , . gulp-changed - . , , - gulp-plumber.





webp- . src, build, , path-intellisense .





tasks/webp.js
const {
	src
} = require('gulp');
const webpConv = require('gulp-webp');
const changed = require('gulp-changed');
const multiDest = require('gulp-multi-dest');
const plumber = require('gulp-plumber');

module.exports = function webp() {
	return src('build/img/**/*.+(png|jpg|jpeg)')
		.pipe(plumber())
		.pipe(changed('build/img', {
			extension: '.webp'
		}))
		.pipe(webpConv())
		.pipe(multiDest(['src/img', 'build/img']))
}
      
      



- SVG. : svg css svg-. , , - . , . , svg- , . .





, svg . gulp-svgmin.





svg background-image gulp-svg-css-pseudo. gulp-svg-css, , . , ::before



::after.



, . , myicon.svg, --svg__myicon



, --svg__myicon-before



--svg__myicon-after



, background-image . , ( ):





.--svg__myicon,.--svg__myicon-before::before,.--svg__myicon-after::after{
    background-image: url("data:image/svg+xml;charset=utf8, %3Csvg width='8' height='6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M.228 1.635A1 1 0 011 0h6a1 1 0 01.772 1.635L4.808 5.589a.999.999 0 01-1.616 0L.228 1.635z' fill='%232C2D2E'/%3E%3C/svg%3E");
}
.--svg__myicon-before::before {
    content:'';
}
.--svg__myicon-after::after {
    content:'';
}
      
      



, src/svg/css , svg.scss src/scss/base. :





tasks/svg_css.js
const {
	src,
	dest
} = require('gulp');
const svgmin = require('gulp-svgmin');
const svgCss = require('gulp-svg-css-pseudo');

module.exports = function svg_css() {
	return src('src/svg/css/**/*.svg')
		.pipe(svgmin({
			plugins: [{
					removeComments: true
				},
				{
					removeEmptyContainers: true
				}
			]
		}))
		.pipe(svgCss({
			fileName: '_svg',
			fileExt: 'scss',
			cssPrefix: '--svg__',
			addSize: false
		}))
		.pipe(dest('src/scss/global'))
}
      
      



svg-. , svg , . ID ( ) css. gulp-svg-sprite :





tasks/svg_sprite.js
const {
	src,
	dest
} = require('gulp');
const svgmin = require('gulp-svgmin');
const sprite = require('gulp-svg-sprite');

module.exports = function svg_sprite() {
	return src('src/svg/**/*.svg')
		.pipe(svgmin({
			plugins: [{
					removeComments: true
				},
				{
					removeEmptyContainers: true
				}
			]
		}))
		.pipe(sprite({
			mode: {
				stack: {
					sprite: '../sprite.svg'
				}
			}
		}))
		.pipe(dest('src/img'))
}
      
      



src/img/sprite.svg svg. html : <img src="sprite.svg#myIconFileName">



:





<svg class="img">
    <use xlink:href="sprite.svg#myIconFileName"></use>
</svg>
      
      



(, , css), . : <img src="sprite.svg#css--myIconFileName">







svg html . , , .






. ttf woff woff2. 2021 , woff Internet Explorer 9. IE9 ? : gulp-ttftowoff2 gulp-ttf2woff, . :





tasks/ttf.js
const {
	src,
	dest
} = require('gulp');
const changed = require('gulp-changed');
const ttf2woff2 = require('gulp-ttftowoff2');
const ttf2woff = require('gulp-ttf2woff');

module.exports = function ttf(done) {
	src('src/fonts/**/*.ttf')
		.pipe(changed('build/fonts', {
			extension: '.woff2',
			hasChanged: changed.compareLastModifiedTime
		}))
		.pipe(ttf2woff2())
		.pipe(dest('build/fonts'))

	src('src/fonts/**/*.ttf')
		.pipe(changed('build/fonts', {
			extension: 'woff',
			hasChanged: changed.compareLastModifiedTime
		}))
		.pipe(ttf2woff())
		.pipe(dest('build/fonts'))
	done();
}
      
      



, , . , , . , . , -, src/scss/base



_mixins.scss



. , . :





src/scss/base/_mixins.scss
@mixin font-face($name, $file, $weight: 400, $style: normal) {
	@font-face {
		font-family: "#{$name}";
		src: local("#{$file}"),
		url('../fonts/#{$file}.woff2') format('woff2'),
		url('../fonts/#{$file}.woff') format('woff');
		font-weight: $weight;
		font-style: $style;
		font-display: swap;
	}
}
      
      



:





  • $name



    - ;





  • $file



    - ;





  • $weight



    - (- 400, , - )





  • $style



    - ( - normal)





, , .





, . , , . nodeJS , fs. nodejs, - : const fs = require('fs');







. , , , - , .





let srcFonts = 'src/scss/_local-fonts.scss';
let appFonts = 'build/fonts/';
      
      



( @MaxGraph ), Gulp . , :





tasks/fonts.js
const fs = require('fs');
const chalk = require('chalk');

let srcFonts = 'src/scss/_local-fonts.scss';
let appFonts = 'build/fonts/';
module.exports = function fonts(done) {
	fs.writeFile(srcFonts, '', () => {});
	fs.readdir(appFonts, (err, items) => {
		if (items) {
			let c_fontname;
			for (let i = 0; i < items.length; i++) {
				let fontname = items[i].split('.'),
					fontExt;
				fontExt = fontname[1];
				fontname = fontname[0];
				if (c_fontname != fontname) {
					if (fontExt == 'woff' || fontExt == 'woff2') {
						fs.appendFile(srcFonts, `@include font-face("${fontname}", "${fontname}", 400);\r\n`, () => {});
						console.log(chalk `
{bold {bgGray Added new font: ${fontname}.}
----------------------------------------------------------------------------------
{bgYellow.black Please, move mixin call from {cyan src/scss/_local-fonts.scss} to {cyan src/scss/_fonts.scss} and then change it!}}
----------------------------------------------------------------------------------
`);
					}
				}
				c_fontname = fontname;
			}
		}
	})
	done();
}
      
      



src/scss/_local-fonts.scss



, . , :





Added new font: YoyrFont.
----------------------------------------------------------------------------------
Please, move mixin call from src/scss/_local-fonts.scss to src/scss/_fonts.scss and then change it.
----------------------------------------------------------------------------------
      
      



, : " : . , src/scss/_local-fonts.scss



src/scss/_fonts.scss



". , . src/scss/_fonts.scss



- , .





, , ( , ..). src/scss/_local-fonts.scss



:





@include font-face("Arial", "Arial", 400);
@include font-face("ArialBold", "ArialBold", 400);
@include font-face("ArialItalic", "ArialItalic", 400);
      
      



, . , , font-weight: 700, font-family: "ArialBold". , . , , . "Arial". - ( ). . 400 700. , , . , . :





@include font-face("Arial", "Arial", 400);
@include font-face("Arial", "ArialBold", 700);
@include font-face("Arial", "ArialItalic", 400, italic);
      
      



src/scss/_fonts.scss



, , , . , src/scss/_local-fonts.scss



.






Gulp , - . browser-sync. nodejs . - html- php . . html.





tasks/bs_html.js
const bs = require('browser-sync');

module.exports = function bs_html() {
	bs.init({
		server: {
			baseDir: 'build/',
			host: '192.168.0.104',
		},
		callbacks: {
			ready: function (err, bs) {
				bs.addMiddleware("*", function (req, res) {
					res.writeHead(302, {
						location: "404.html"
					});
					res.end("Redirecting!");
				});
			}
		},
		browser: 'chrome',
		logPrefix: 'BS-HTML:',
		logLevel: 'info',
		logConnections: true,
		logFileChanges: true,
		open: true
	})
}
      
      



host IP- , . , IP- , . - 404, ( index.html). , .





php . , : openserver, wamp .





tasks/bs_php.js
const bs = require('browser-sync');

module.exports = function bs_php() {
	bs.init({
		browser: ['chrome'],
		watch: true,
		proxy: '',
		logLevel: 'info',
		logPrefix: 'BS-PHP:',
		logConnections: true,
		logFileChanges: true,
	})
}
      
      



browser-sync pipe . - : , . pipe : .pipe(bs.stream())



.





html, scss js, php, . , pipe.





!

, - , gulp-size, " ", . pipe . .





. - , , , . , : html, php, scss, js, json ( , ), src, build (, webp ?), svg, . :





tasks/watch.js
const {
	watch,
	parallel,
	series
} = require('gulp');

module.exports = function watching() {
	watch('src/**/*.html', parallel('html'));
	watch('src/**/*.php', parallel('php'));
	watch('src/**/*.scss', parallel('style'));
	watch('src/**/*.js', parallel('dev_js'));
	watch('src/**/*.json', parallel('html'));
	watch('src/img/**/*.+(png|jpg|jpeg|gif|svg|ico)', parallel('rastr'));
	watch('build/img/**/*.+(png|jpg|jpeg)', parallel('webp'));
	watch('src/svg/css/**/*.svg', series('svg_css', 'style'));
	watch('src/svg/sprite/**/*.svg', series('svg_sprite', 'rastr'));
	watch('src/fonts/**/*.ttf', series('ttf', 'fonts'));
}
      
      



- parallel series. , , - , , .





. watch , .





. Gulp , .






FTP

. vinyl-ftp, , . . build/



, , . chalk.





tasks/deploy.js
const {
	src
} = require('gulp');
const ftp = require('vinyl-ftp');
const ftpSettings = require('../tasks/ftp_settings');
const chalk = require('chalk');
const connect = ftp.create(ftpSettings);

module.exports = function deploy() {
	return src(['build/**/*.*', '!build/**/*.map'])
		.pipe(connect.newer('public_html/'))
		.pipe(connect.dest('public_html/'))
		.on('success', () => console.log(`Finished deploing ./build to https://${chalk.blueBright(ftpSettings.host)}`))
}
      
      



connect



- , - , , . , Github . tasks/ftp_settings.json gitignore, :





{
	"host": "yourhosting.com",
	"user": "username",
	"pass": "*********",
	"parallel": 10
}
      
      



ftp- public_html/



, newer dest.






GULP- NPM-

gulp-, , .





gulp-: default php, , , npm , .





gulpfile.js, gulp. , hello:





exports.style = tasks.style;
exports.libs_style = tasks.libs_style;
exports.build_js = tasks.build_js;
exports.libs_js = tasks.libs_js;
exports.dev_js = tasks.dev_js;
exports.html = tasks.html;
exports.php = tasks.php;
exports.rastr = tasks.rastr;
exports.webp = tasks.webp;
exports.svg_css = tasks.svg_css;
exports.svg_sprite = tasks.svg_sprite;
exports.ttf = tasks.ttf;
exports.fonts = tasks.fonts;
exports.bs_html = tasks.bs_html;
exports.bs_php = tasks.bs_php;
exports.watch = tasks.watch;
exports.deploy = tasks.deploy;
      
      



, Gulp :





html ( - -)
exports.default = gulp.parallel(
	exports.libs_style,
	exports.style,
	exports.libs_js,
	exports.dev_js,
	exports.rastr,
	exports.webp,
	exports.svg_css,
	exports.svg_sprite,
	exports.ttf,
	exports.fonts,
	exports.html,
	exports.bs_html,
	exports.watch
)
      
      



php
exports.dev_php = gulp.parallel(
	exports.libs_style,
	exports.svg_css,
	exports.fonts,
	exports.style,
	exports.libs_js,
	exports.dev_js,
	exports.rastr,
	exports.webp,
	exports.svg_sprite,
	exports.ttf,
	exports.php,
	exports.bs_php,
	exports.watch
)
      
      



gulpfile.js :





gulpfile.js
const gulp = require('gulp');
const requireDir = require('require-dir');
const tasks = requireDir('./tasks');

exports.style = tasks.style;
exports.libs_style = tasks.libs_style;
exports.build_js = tasks.build_js;
exports.libs_js = tasks.libs_js;
exports.dev_js = tasks.dev_js;
exports.html = tasks.html;
exports.php = tasks.php;
exports.rastr = tasks.rastr;
exports.webp = tasks.webp;
exports.svg_css = tasks.svg_css;
exports.svg_sprite = tasks.svg_sprite;
exports.ttf = tasks.ttf;
exports.fonts = tasks.fonts;
exports.bs_html = tasks.bs_html;
exports.bs_php = tasks.bs_php;
exports.watch = tasks.watch;
exports.deploy = tasks.deploy;

exports.default = gulp.parallel(
	exports.libs_style,
	exports.style,
	exports.libs_js,
	exports.dev_js,
	exports.rastr,
	exports.webp,
	exports.svg_css,
	exports.svg_sprite,
	exports.ttf,
	exports.fonts,
	exports.html,
	exports.bs_html,
	exports.watch
)
exports.dev_php = gulp.parallel(
	exports.libs_style,
	exports.style,
	exports.libs_js,
	exports.dev_js,
	exports.rastr,
	exports.webp,
	exports.svg_css,
	exports.svg_sprite,
	exports.ttf,
	exports.fonts,
	exports.php,
	exports.bs_php,
	exports.watch
)
      
      



package.json npm-, . "scripts" - . :





  "scripts": {
    "html": "gulp",
    "php": "gulp dev_php",
    "build": "gulp libs_style && gulp svg_css && gulp ttf && gulp fonts && gulp style && gulp libs_js && gulp build_js && gulp rastr && gulp webp && gulp svg_sprite && gulp html && gulp php",
    "ftp": "gulp deploy",
    "build-ftp": "npm run build && npm run ftp"
  },
      
      



  • html Gulp html-;





  • php Gulp php-;





  • build build ;





  • ftp build ( .map) ftp-;





  • build-ftp build ftp .






html, - , . html. (index.html) :





<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
  <main>
    
  </main>
</body>
</html>
      
      



, :





src/components/page-blocks/_head.html
<html lang="@@lang">

<html lang="@@lang">

<head>
	<meta charset="UTF-8">
	<meta name="viewport"
				content="width=device-width, initial-scale=1.0">
	<meta name="description"
				content="@@description">
	<meta name="keywords"
				content="@@keywords">
	<link rel="shortcut icon"
				href="@@favicon.svg"
				type="image/svg+xml">
	<link rel="shortcut icon"
				href="@@favicon.webp"
				type="image/webp">
	<link rel="shortcut icon"
				href="@@favicon.png"
				type="image/x-icon">
	<link rel="stylesheet"
				href="css/libs.min.css">
	<link rel="stylesheet"
				href="css/style.min.css">
	<title>@@title</title>
</head>
      
      



... head :





<!DOCTYPE html>
@@include('components/page-blocks/_head.html',{
"lang":"en",
"title":"Easy-webdev-startpack v3.0",
"description":"Gulp pack for easy html/php markup development",
"keywords":"",
"favicon":"img/favicons/favicon",
})

<body>
	<main class="main">
    
  </main>
</body>

</html>
      
      



, . @@include . - , , - json- ( json, ), - , . , :





src/components/page-blocks/...

_header.html

<header class="header"></header>
      
      



_footer.html

<footer class="footer"></footer>
      
      



_scripts.html

<script src="js/libs.min.js"></script>
<script src="js/main.min.js"></script>
      
      



:





<!DOCTYPE html>
@@include('components/page-blocks/_head.html',{
"lang":"en",
"title":"Easy-webdev-startpack v3.0",
"description":"Gulp pack for easy html/php markup development",
"keywords":"",
"favicon":"img/favicons/favicon",
})

<body>
	@@include('components/page-blocks/_header.html')
	<main class="main"></main>
	@@include('components/page-blocks/_footer.html')
	@@include('components/page-blocks/_scripts.html')
</body>

</html>
      
      



Gulp , head, header, footer . gulp build, html-:





build / index.html
build/index.html

. , style.scss. , , :





@import 'base/*.scss';
@import 'global/*.scss';
@import '../components/**/*.scss';
@import '**/_*.scss';
      
      



src/scss/base _01_normalize.scss



: . , , . normalize.css. , normalize , , , .





src/scss/base/_mixins.scss. , :





@mixin bg ($size:"contain", $position: "center") {
	background-size: #{$size};
	background-position: #{$position};
	background-repeat: no-repeat;
}
      
      



. @include bg



:





body {
	background-size: contain;
	background-position: center;
	background-repeat: no-repeat;
}
      
      



, - ( , ):





@mixin btn_anim($scaleMax:1.05, $scaleMin:0.95) {
	transform-origin: center center;
	transition: all ease-out 240ms;

	&:hover {
		transform: scale($scaleMax);
	}

	&:focus{
		outline: transparent;
	}

	&:focus-visible {
		transform: scale($scaleMax) translateY(-5%);
	}

	&:active {
		transform: scale($scaleMin);
	}
}
      
      



. .





@mixin no-btn ($display:"inline-block") {
	padding: 0;
	margin: 0;
	border: 0;
	background-color: transparent;
	border-radius: 0;
	cursor: pointer;
	appearance: none;
	display: #{$display};
}
      
      



, . transition:





@mixin transit ($tr:0.24) {
	transition: all #{$tr}s;
}
      
      



:





@mixin container($max-width:"120rem",$padding:"2rem"){
	width: 100%;
	max-width: #{$max-width};
	padding: 0 #{$padding};
	margin: 0 auto;
}
      
      



src/scss/global/_global.scss



"" . , .





-, box-sizing: border-box :





*,
*::before,
*::after {
	box-sizing: border-box;
}
      
      



-, :





.flex {
	display: flex;
	align-items: flex-start;
	justify-content: flex-start;
}
.--just-space {
	justify-content: space-between;
}

.--just-center {
	justify-content: center;
}

.--just-end {
	justify-content: flex-end;
}

.--align-str {
	align-items: stretch;
}

.--align-center {
	align-items: center;
}

.--align-end {
	align-items: flex-end;
}

.--dir-col{
	flex-direction: column;
}
      
      



-, html body :





html{
	font-size: 16px;
}

html,
body {
	min-height: 100%;
	position: relative;
}

body{
	font-size: 1rem;
}
      
      



, . :





ul,
ol,
li,
p,
h1,
h2,
h3,
h4,
h5,
h6 {
	margin: 0;
}
      
      



, :





src/scss/base/_mixins.scss
@mixin font-face($name, $file, $weight: 400, $style: normal) {
	@font-face {
		font-family: "#{$name}";
		src: local("#{$file}"),
		url('../fonts/#{$file}.woff2') format('woff2'),
		url('../fonts/#{$file}.woff') format('woff');
		font-weight: $weight;
		font-style: $style;
		font-display: swap;
	}
}

@mixin bg ($size:"contain", $position: "center") {
	background-size: #{$size};
	background-position: #{$position};
	background-repeat: no-repeat;
}

@mixin btn_anim($scaleMax:1.05, $scaleMin:0.95) {
	transform-origin: center center;
	transition: all ease-out 240ms;

	&:hover {
		transform: scale(#{$scaleMax});
	}

	&:focus {
		outline: transparent;
	}

	&:focus-visible {
		transform: scale(#{$scaleMax}) trahslateY(-5%);
	}

	&:active {
		transform: scale(#{$scaleMin});
	}
}

@mixin no-btn ($display:"inline-block") {
	padding: 0;
	margin: 0;
	border: 0;
	background-color: transparent;
	border-radius: 0;
	cursor: pointer;
	appearance: none;
	display: #{$display};
}

@mixin transit ($tr:0.24) {
	transition: all #{$tr}s;
}

@mixin container($max-width:"120rem", $padding:"2rem") {
	width: 100%;
	max-width: #{$max-width};
	padding: 0 #{$padding};
	margin: 0 auto;
}
      
      



src/scss/global/_global.scss
*,
*::before,
*::after {
	box-sizing: border-box;
}

.flex {
	display: flex;
	align-items: flex-start;
	justify-content: flex-start;
}

.--just-space {
	justify-content: space-between;
}

.--just-center {
	justify-content: center;
}

.--just-end {
	justify-content: flex-end;
}

.--align-str {
	align-items: stretch;
}

.--align-center {
	align-items: center;
}

.--align-end {
	align-items: flex-end;
}

.--dir-col {
	flex-direction: column;
}

html {
	font-size: 16px;
}

html,
body {
	min-height: 100%;
	position: relative;
}

body {
	font-size: 1rem;
}

ul,
ol,
li,
p,
h1,
h2,
h3,
h4,
h5,
h6 {
	margin: 0;
}
      
      



, . ! .






howto

, @@include- html , , . , svg html, .





. @@include @@loop, , . , , , @@loop . ! loop includ' - .





. . . components , html, scss js (, ). Scss js , .






, . , , . 10 , , .





If you know how you can improve the build, refactor some task, then write about it in the comments, or better, leave your pull-request in the repository. I am always open to improvement and ready to discuss.








All Articles