- Архитектура проекта
- Src/assets
- Src/assets/scss/base
- Src/assets/svg
- Src/blocks
- Src/layouts
- Страницы
- Таск sass
- Таск scripts
- Таск twig
- Таск browser-sync
- Таск img
- Таск svg-min
- Таск build
- Таск pages-list
- Таск watch
- Таск default
В этом документе описан наш gulp файл который мы используем в ежедневной работе над простыми проектами. Он постоянно меняется и дополняется под наши нужды. Описываем в первую очередь для себя и надеемся что кому-то будет полезно.
Цель нашего gulp файла - быть простым и гибким, легко изменяться и быть понятным.
Стек используемых технологий: sass twig browser-sync imagemin autoprefixer
Архитектура проекта
front
├── pages
│ ├── fonts
│ │ └── Roboto_mono
│ ├── img
│ │ ├── logo.png
│ │ └── logo.webp
│ ├── index.html
│ ├── main.min.js
│ ├── pages.html
│ ├── style.css
│ └── svg
├── src
│ ├── assets
│ │ ├── img
│ │ │ └── logo.png
│ │ ├── js
│ │ │ ├── jquery.min.js
│ │ │ ├── main.js
│ │ │ └── validator.js
│ │ ├── scss
│ │ │ ├── base
│ │ │ │ ├── default.scss
│ │ │ │ ├── fonts.scss
│ │ │ │ ├── mixins.scss
│ │ │ │ ├── normalize.scss
│ │ │ │ ├── typography.scss
│ │ │ │ └── variables.scss
│ │ │ └── style.scss
│ │ └── svg
│ │ └── ... все svg
│ ├── blocks
│ │ ├── footer
│ │ │ ├── footer.twig
│ │ │ └── footer.scss
│ │ └── header
│ │ ├── header.twig
│ │ └── header.scss
│ ├── layouts
│ │ └── layout.twig
│ ├── custom-page
│ │ ├── custom-page.twig
│ │ └── custom-page.scss
│ ├── index.twig
│ └── pages.twig
├── babel.config.json
├── package.json
└── gulp.js
Проект состоит из двух основных папок pages и src в первой хранится результат сборки(туда лезть не стоит) в src хранятся исходники, то место где происходит сама работа.
Src/assets
Картинки, svg, общий js, общий scss
scss хранится в папке src/assets/scss - основной файл style.scss в нем подключаются все стили компонент (да - это делается в ручную так как важен порядок).
Src/assets/scss/base
-
default.scss
Основные глобальные стили, по умолчанию прописан контейнер -
fonts.scss
Подключение всех шрифтов проекта, по умолчанию пусто - комментарий с примером правильного подключения. Сервис для конвертирования шрифтов - Online Font Converter -
mixins.scss
Файл для миксинов - по умочанию миксин для адаптивной разработки -
normalize.scss
Стандартный normalize убирающий дефолтные стили браузеров -
typography.scss
Прописываем дефолтные стили для всех инлайновых элементов -
variables.scss
Файл переменных, по умолчанию набор часто используемых переменных
Src/assets/svg
Мы не используем спрайты, храним все svg в отдельной папке, подключаются svg с помощью twig include. Все svg минифицируются и кладутся в pages.
Src/blocks
Папка содержит все блоки/компоненты , каждый компонент хранится в своей папке. Пример:
blocks
blocks
└── footer
├── footer.twig
├── footer.js
└── footer.scss
Все относящееся к компоненту должно храниться в папке компонента. Js всех компонент собирается в min файл /pages/main.min.js
Src/layouts
Папка содержит шаблоны проекта, которые наследуются страницами {% extends "layouts/layout.twig" %} по умолчанию имеем стандартный шаблон с подключенными стилями и js и размеченными блоками под контент.
Страницы
Страницы хранятся в корне проекта - как twig файл (если это простая страница) либо как папка, пример:
├── custom-page
│ ├── custom-page.twig
│ └── custom-page.scss
├── index.twig
Таск sass
В этом таске мы превращаем scss
в css
и кладем его в один файл src/assets/scss/style.scss
предварительно объединяем медиа запросы и минифицируем итоговый css
с помощью clean-css. Ну и в конце обновляем браузер.
gulp.task('sass', () =>
{
return gulp.src('src/assets/scss/style.scss')
.pipe(sass({includePaths: ['src/']}).on('error', sass.logError))
.pipe(autoprefixer(['last 10 versions', '> 1%'], {cascade: true}))
.pipe(gcmq())
.pipe(cleanCSS())
.pipe(gulp.dest('pages'))
.pipe(browserSync.reload({stream: true}));
});
Таск scripts
В этом таске мы проходимся по всем js файлам прогоняем их через babel объединяем минифицируем и кладем в pages/main.min.js
var jsFiles = ['src/assets/js/*.js', 'src/**/*.js'];
// таск для объединения js файлов
gulp.task('scripts', () =>
{
process.env.NODE_ENV = "release";
return gulp.src(jsFiles)
.pipe(babel())
.pipe(concat('main.min.js'))
.pipe(uglify())
.pipe(gulp.dest('pages'))
.pipe(browserSync.reload({stream: true}));
});
Таск twig
Запуск шаблонизатора, проходимся по всем twig файлам кроме /src/pages.twig и кладет результат в pages/. В конце обновляется страница.
const htmlbeautifyOptions = {
indentSize: 4,
unformatted: [
'abbr', 'area', 'b', 'bdi', 'bdo', 'br', 'cite',
'code', 'data', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'ins', 'kbd', 'keygen', 'map', 'mark', 'math', 'meter', 'noscript',
'object', 'output', 'progress', 'q', 'ruby', 's', 'samp', 'small',
'strong', 'sub', 'sup', 'template', 'time', 'u', 'var', 'wbr', 'text',
'acronym', 'address', 'big', 'dt', 'ins', 'strike', 'tt', 'a'
],
"indent_level": 1,
"indent_with_tabs": true,
};
gulp.task('twig', function ()
{
return gulp.src(['./src/*.twig','!./src/pages.twig'])
.pipe(plumber())
.pipe(twig({base:'./src/'}))
.pipe(htmlbeautify(htmlbeautifyOptions))
.pipe(gulp.dest("pages/",))
.pipe(browserSync.reload({stream: true}));
});
Таск browser-sync
Синхронизирует работу браузера. Помогает обновлять браузер при изменении файлов.
gulp.task('browser-sync', () =>
{
browserSync({
server: {baseDir: './pages/'},
startPath: './index.html',
serveStaticOptions: {extensions: ["html"] },
ghostMode: {scroll: false },
notify: false,
});
});
Таск img
Таск сжимает картинки формата png и jpg находящиеся в папке src/assets/img/ без потери качества. Конвертирует их в формат webp и переносит сжатый вариант и webp в папку pages/img/.
gulp.task('img', function()
{
return gulp.src(['src/assets/img/*.png', 'src/assets/img/*.jpg']) // откуда брать картинки
.pipe(imagemin([imagemin.gifsicle(), imagemin.optipng(), imagemin.svgo() ]))
.pipe(gulp.dest('pages/img/'))
.pipe(webp())
.pipe(gulp.dest('pages/img/'));
});
Таск svg-min
Таск обрабатывает все svg файлы находящие в папке src/assets/svg/ с помощью gulp-svgmin, оптимизирует их и удаляет лишние свойства и переносит файлы в pages/svg.
Список всех плагинов для оптимизатора gulp-svgmin
gulp.task('svg-min', () =>
{
return gulp.src('src/assets/svg/*.svg')
.pipe(
svgmin(file =>
{
const { relative } = file;
const prefix = path.basename(relative, path.extname(relative));
return {
js2svg: {pretty: true, },
plugins: [
{cleanupIDs: { prefix: '${prefix}-' + Math.floor(Math.random() * (100 - 10)) + 10 }, },
{removeDoctype: true, },
{removeXMLProcInst: true, },
{removeViewBox: false },
{removeTitle: true, },
{removeDesc: { removeAny: true }, },
{convertTransform: {}, },
],
};
}))
.pipe(
cheerio({
run: ($, file) =>
{
const $clipPath = $('clipPath');
const $mask = $('mask');
let $defs = $('defs');
const hasClipPath = $clipPath.length > 0;
const hasMask = $mask.length > 0;
const hasDefs = $defs.length > 0;
if (!hasClipPath && !hasMask) return;
if (!hasDefs)
{
$defs = $(' ');
$defs.prependTo('svg');
}
function copyToDefs(i, el)
{
const $el = $(el);
const $clone = $el.clone();
$clone.appendTo($defs);
$el.remove();
}
if (hasClipPath) $clipPath.each(copyToDefs);
if (hasMask) $mask.each(copyToDefs);
},
parserOptions: {xmlMode: true, },
})
)
.pipe(gulp.dest('pages/svg'));
});
Таск build
Запускает другие таски для финальной сборки проекта.
gulp.task('build', gulp.series('svg-min', 'sass', 'twig', 'scripts', 'img', async () => { console.log('builded');}));
Таск pages-list
Таск собирает список путей ко всем страницам (html файлам) из папки pages/ кроме pages/pages.html, собирает из него массив состоящий из названий фалов и передает этот массив в src/pages.twig. В этом файле мы проходимся циклом по массиву и выводим список всех имен страниц для удобной навигации по страницам людям которые будут тестировать верстку. Дальше этот файл переносится через gulp-twig в папку pages.
За место http://localhost:3000/ пишем свой необходимый путь или домен.
// фрагмент из файла src/pages.twig
{% for page in fileList %}
<li>
{{ page }}
</li>
{% endfor %}
gulp.task('pages-list', () =>
{
let fileList = [];
let pathSetting = ['./pages/*.html', '!./pages/pages.html'];
return gulp.src(pathSetting)
.pipe(map(function(file, cb)
{
var f = file.path.replace(file.cwd, '.');
fileList.push((f).substr((f).lastIndexOf('/') + 1,(f).lastIndexOf('.') - 1));
cb(null, null);
}))
.on('end', () =>
{
gulp.src('./src/pages.twig')
.pipe(
twig({
base:'./src/',
data: { fileList: fileList }
})
)
.pipe(gulp.dest('./pages/'));
});
});
Таск watch
Таск следит за изменениями файлов и вызывает другие таски.
gulp.task('watch', function()
{
gulp.watch(['scss/**/*.scss','src/**/*.scss'], gulp.parallel('sass'));
gulp.watch('src/**/*.twig', gulp.parallel('twig'));
gulp.watch('src/**/*.twig', gulp.parallel('pages-list'));
gulp.watch(['src/**/*.js'], gulp.parallel('scripts'));
gulp.watch('src/**/*.js', gulp.parallel(() => { browserSync.reload(); }));
gulp.watch('img/*', gulp.parallel(() => { browserSync.reload(); }));
});
Таск default
Таск по умолчанию. Запускается при вводе в терминал gulp. Запускает локальный сервер http://localhost:3000/ и другие таски для разработки в реальном времени и сборки проекта. В нем используются другие таски которые перезагружают локальный сервер по необходимости, например при изменении и сборке js файлов.
gulp.task('default', gulp.parallel('watch', 'browser-sync', 'sass', 'twig', 'svg-min', 'pages-list', 'scripts', () => { console.log('dev start');}));