Commit e3a08701 authored by Nikolay Gromov's avatar Nikolay Gromov

Запилил спрайты

parent 664308b1
...@@ -4,10 +4,10 @@ build/* ...@@ -4,10 +4,10 @@ build/*
src/pug/mixins.pug src/pug/mixins.pug
src/js/entry.js src/js/entry.js
src/scss/style.scss src/scss/style.scss
src/blocks/sprite-svg/img/sprite.svg
src/blocks/sprite-svg/img/sprite-svg.svg
src/blocks/sprite-png/sprite-png.scss src/blocks/sprite-png/sprite-png.scss
src/blocks/sprite-png/img/sprite-*.png src/blocks/sprite-png/img/sprite-*.png
faviconData.json faviconData.json
__MACOSX __MACOSX
......
...@@ -21,8 +21,7 @@ src/ ...@@ -21,8 +21,7 @@ src/
1. Создаётся глобальная переменная `config` с настройками (из `./config.js`). 1. Создаётся глобальная переменная `config` с настройками (из `./config.js`).
2. Очищается папка сборки (`./build/`). 2. Очищается папка сборки (`./build/`).
3. Записывается `./src/pug/mixins.pug` (инклуды всех pug-файлов блоков, независимо от использования на проекте). Инклуд добавляется только если в папке блока есть одноимённый блоку pug-файл. 3. Записывается `./src/pug/mixins.pug` и компилируются в html файлы страниц (`./src/pages/`). **В процессе обновляется список блоков** (`config.blocks`), если есть какие-то новые блоки, записывается файл `./config.js`.
3. Pug-файлы страниц (`./src/pages/`) компилируются в html и пишутся в `./build/`. **В процессе обновляется список блоков** (`config.blocks`), туда попадают все БЭМ-блоки из разметки страниц (кроме страниц из `config.notGetBlocks`), кроме исключений из `config.ignoredBlocks`. Если есть какие-то новые блоки, записывается файл `./config.js`.
4. Записывается `./src/scss/style.scss`, в котором: 4. Записывается `./src/scss/style.scss`, в котором:
- Импорты файлов из `config.addStyleBefore`. - Импорты файлов из `config.addStyleBefore`.
- Импорты файлов БЭМ-блоков, использующихся на проекте (из `config.blocks`, но только если сами scss-файлы существуют в папках блоков). - Импорты файлов БЭМ-блоков, использующихся на проекте (из `config.blocks`, но только если сами scss-файлы существуют в папках блоков).
...@@ -32,48 +31,20 @@ src/ ...@@ -32,48 +31,20 @@ src/
- Подключения js-файлов js-файлов БЭМ-блоков, использующихся на проекте (из `config.blocks`, но только если сами js-файлы существуют в папках блоков). - Подключения js-файлов js-файлов БЭМ-блоков, использующихся на проекте (из `config.blocks`, но только если сами js-файлы существуют в папках блоков).
- Подключения файлов из `config.addJsAfter`. - Подключения файлов из `config.addJsAfter`.
6. Компилируется и обрабатывается PostCSS-ом Sass, собирается JS. 6. Компилируется и обрабатывается PostCSS-ом Sass, собирается JS.
7. Копируются все статичные файлы (список в `config.copyAssets`). 7. Копируются все статичные файлы (список в `config.copyAssets`) и картинки БЭМ-блоков (подпапка `img/` в папке используемого блока).
8. Запускается слежение и сервер.
9. PROFIT
998. Запускается слежение и сервер.
999. PROFIT
### Изменение любого стилевого файла
- Компилируем стили.
- Обновляем CSS страницы.
### Добавление или удаление стилевого файла
- `configOld = config`
- Формируем актуальный конфиг `config`:
- Добавляем не касающиеся блоков разделы из `configOld`.
- Обходим `blocksList` и проверяем для каждого блока существование стилевого файла. Про js-файл и картинки не проверяем, берем существующие данные. Записываем данные, идентичные старому конфигу по структуре.
- Записываем актуальный конфиг в файл `config.json`.
- Формируем список стилевых файлов: файлы ДО, файлы блоков (если есть), файлы ПОСЛЕ.
- Перезаписываем ДП стилей.
- Компилируем стили.
- Обновляем CSS страницы.
### Изменение любого js-файла
### Изменение в папке, откуда собирается растровый спрайт ### Изменение в папке, откуда собирается растровый спрайт
### Изменение в папке, откуда собирается векторный спрайт ### Изменение в папке, откуда собирается векторный спрайт
### Изменение в папке добавочных картинок ### Изменение в папке добавочных картинок
### Изменение в папке добавочных файлов ### Изменение в папке добавочных файлов
### Изменение файла `config.json` ### Изменение файла `config.json`
добавить возможность включать в сборку блоки, не найденные на странице
## СТАРОЕ ## СТАРОЕ
......
...@@ -7,6 +7,10 @@ let config = ...@@ -7,6 +7,10 @@ let config =
"ignoredBlocks": [ "ignoredBlocks": [
"no-js" "no-js"
], ],
"alwaysAddBlocks": [
"sprite-svg",
"sprite-png"
],
"blocks": [ "blocks": [
"page", "page",
"page-header", "page-header",
...@@ -15,8 +19,8 @@ let config = ...@@ -15,8 +19,8 @@ let config =
"burger", "burger",
"page-footer", "page-footer",
"some-new-class", "some-new-class",
"haters", "sprite-svg",
"haters2" "sprite-png"
], ],
"addStyleBefore": [ "addStyleBefore": [
"./src/scss/functions.scss", "./src/scss/functions.scss",
...@@ -38,7 +42,8 @@ let config = ...@@ -38,7 +42,8 @@ let config =
}, },
"dir": { "dir": {
"src": "./src/", "src": "./src/",
"build": "./build/" "build": "./build/",
"blocks": "./src/blocks/"
} }
}; };
......
...@@ -7,6 +7,7 @@ const plumber = require('gulp-plumber'); ...@@ -7,6 +7,7 @@ const plumber = require('gulp-plumber');
const del = require('del'); const del = require('del');
const pug = require('gulp-pug'); const pug = require('gulp-pug');
const through2 = require('through2'); const through2 = require('through2');
const rename = require('gulp-rename');
const replace = require('gulp-replace'); const replace = require('gulp-replace');
const getClassesFromHtml = require('get-classes-from-html'); const getClassesFromHtml = require('get-classes-from-html');
const jsonFormat = require('json-format'); const jsonFormat = require('json-format');
...@@ -28,6 +29,11 @@ const cleanss = require('gulp-cleancss'); ...@@ -28,6 +29,11 @@ const cleanss = require('gulp-cleancss');
const inlineSVG = require('postcss-inline-svg'); const inlineSVG = require('postcss-inline-svg');
const objectFitImages = require('postcss-object-fit-images'); const objectFitImages = require('postcss-object-fit-images');
const cpy = require('cpy'); const cpy = require('cpy');
const svgstore = require('gulp-svgstore');
const svgmin = require('gulp-svgmin');
const spritesmith = require('gulp.spritesmith');
const merge = require('merge-stream');
const imagemin = require('gulp-imagemin');
// Настройки из файла // Настройки из файла
let config = require('./config.js'); let config = require('./config.js');
...@@ -174,10 +180,11 @@ exports.writeJsRequiresFile = writeJsRequiresFile; ...@@ -174,10 +180,11 @@ exports.writeJsRequiresFile = writeJsRequiresFile;
function copyAssets(cb) { function copyAssets(cb) {
for (let item in config.addAssets) { for (let item in config.addAssets) {
let dest = `${dir.build}${config.addAssets[item]}`; let dest = `${dir.build}${config.addAssets[item]}`;
(async () => { // (async () => {
await cpy(item, dest); // await cpy(item, dest);
cpy(item, dest);
console.log(`---------- Скопировано: ${item} -> ${dest}`); console.log(`---------- Скопировано: ${item} -> ${dest}`);
})(); // })();
} }
cb(); cb();
} }
...@@ -193,12 +200,58 @@ function copyImg(cb) { ...@@ -193,12 +200,58 @@ function copyImg(cb) {
(async () => { (async () => {
await cpy(copiedImages, `${dir.build}img`); await cpy(copiedImages, `${dir.build}img`);
console.log(`---------- Скопированы изображения БЭМ-блоков`); console.log(`---------- Скопированы изображения БЭМ-блоков`);
cb();
})(); })();
cb();
} }
exports.copyImg = copyImg; exports.copyImg = copyImg;
function generateSvgSprite(cb) {
let spriteSvgPath = `${dir.blocks}sprite-svg/svg/`;
if(config.blocks.indexOf('sprite-svg') + 1 && fileExist(spriteSvgPath)) {
return src(spriteSvgPath + '*.svg')
.pipe(svgmin(function (file) {
return { plugins: [{ cleanupIDs: { minify: true } }] }
}))
.pipe(svgstore({ inlineSvg: true }))
.pipe(rename('sprite.svg'))
.pipe(dest(`${dir.blocks}sprite-svg/img/`));
}
else {
console.log('неа');
cb();
}
}
exports.generateSvgSprite = generateSvgSprite;
function generatePngSprite(cb) {
let spritePngPath = `${dir.blocks}sprite-png/png/`;
if(config.blocks.indexOf('sprite-png') + 1 && fileExist(spritePngPath)) {
del(`${dir.blocks}sprite-png/img/*.png`);
let fileName = 'sprite-' + Math.random().toString().replace(/[^0-9]/g, '') + '.png';
let spriteData = src(spritePngPath + '*.png')
.pipe(spritesmith({
imgName: fileName,
cssName: 'sprite-png.scss',
padding: 4,
imgPath: '../img/' + fileName
}));
let imgStream = spriteData.img
.pipe(buffer())
.pipe(imagemin([ imagemin.optipng({ optimizationLevel: 5 }) ]))
.pipe(dest(`${dir.blocks}sprite-png/img/`));
let cssStream = spriteData.css
.pipe(dest(`${dir.blocks}sprite-png/`));
return merge(imgStream, cssStream);
}
else {
cb();
}
}
exports.generatePngSprite = generatePngSprite;
function clearBuildDir() { function clearBuildDir() {
return del([ return del([
`${dir.build}**/*`, `${dir.build}**/*`,
...@@ -222,14 +275,12 @@ function serve() { ...@@ -222,14 +275,12 @@ function serve() {
open: false, open: false,
notify: false, notify: false,
}); });
// Файлы разметки страниц (изменение, добавление)
watch([`${dir.src}pages/**/*.pug`], { events: ['change', 'add'], delay: 100 }, series( watch([`${dir.src}pages/**/*.pug`], { events: ['change', 'add'], delay: 100 }, series(
compilePugFast, compilePugFast,
parallel(writeSassImportsFile, writeJsRequiresFile), parallel(writeSassImportsFile, writeJsRequiresFile),
parallel(compileSass, buildJs), parallel(compileSass, buildJs),
reload reload
)); ));
// Файлы разметки страниц (удаление)
watch([`${dir.src}pages/**/*.pug`], { delay: 100 }) watch([`${dir.src}pages/**/*.pug`], { delay: 100 })
.on('unlink', function(path, stats) { .on('unlink', function(path, stats) {
let filePathInBuildDir = path.replace(dir.src.replace('./','') + 'pages/', dir.build).replace('.pug', '.html'); let filePathInBuildDir = path.replace(dir.src.replace('./','') + 'pages/', dir.build).replace('.pug', '.html');
...@@ -238,36 +289,33 @@ function serve() { ...@@ -238,36 +289,33 @@ function serve() {
console.log(`---------- ${filePathInBuildDir} удалён`); console.log(`---------- ${filePathInBuildDir} удалён`);
}); });
}); });
// Файлы разметки БЭМ-блоков (изменение, добавление)
watch([`${dir.blocks}**/*.pug`], { events: ['change', 'add'], delay: 100 }, series( watch([`${dir.blocks}**/*.pug`], { events: ['change', 'add'], delay: 100 }, series(
compilePug, compilePug,
writeSassImportsFile, writeSassImportsFile,
compileSass, compileSass,
reload reload
)); ));
// Файлы разметки БЭМ-блоков (удаление)
watch([`${dir.blocks}**/*.pug`], { events: ['unlink'], delay: 100 }, series(writePugMixinsFile)); watch([`${dir.blocks}**/*.pug`], { events: ['unlink'], delay: 100 }, series(writePugMixinsFile));
// Глобальные pug-файлы, кроме файла примесей (все события)
watch([`${dir.src}pug/**/*.pug`, `!${dir.src}pug/mixins.pug`], { delay: 100 }, series( watch([`${dir.src}pug/**/*.pug`, `!${dir.src}pug/mixins.pug`], { delay: 100 }, series(
compilePugFast, compilePugFast,
parallel(writeSassImportsFile, writeJsRequiresFile), parallel(writeSassImportsFile, writeJsRequiresFile),
parallel(compileSass, buildJs), parallel(compileSass, buildJs),
reload, reload,
)); ));
// Стилевые файлы БЭМ-блоков (любые события)
watch([`${dir.blocks}**/*.scss`], { events: ['all'], delay: 100 }, series(writeSassImportsFile, compileSass)); watch([`${dir.blocks}**/*.scss`], { events: ['all'], delay: 100 }, series(writeSassImportsFile, compileSass));
// Глобальные стилевые файлы, кроме файла с импортами (любые события)
watch([`${dir.src}scss/**/*.scss`, `!${dir.src}scss/style.scss`], { events: ['all'], delay: 100 }, series(compileSass)); watch([`${dir.src}scss/**/*.scss`, `!${dir.src}scss/style.scss`], { events: ['all'], delay: 100 }, series(compileSass));
// Глобальные Js-файлы и js-файлы блоков
watch([`${dir.src}js/**/*.js`, `!${dir.src}js/entry.js`, `${dir.blocks}**/*.js`], { events: ['all'], delay: 100 }, series(writeJsRequiresFile, buildJs, reload)); watch([`${dir.src}js/**/*.js`, `!${dir.src}js/entry.js`, `${dir.blocks}**/*.js`], { events: ['all'], delay: 100 }, series(writeJsRequiresFile, buildJs, reload));
// Изображения БЭМ-блоков
watch([`${dir.blocks}**/img/*.{jpg,jpeg,png,gif,svg,webp}`], { events: ['all'], delay: 100 }, series(copyImg, reload)); watch([`${dir.blocks}**/img/*.{jpg,jpeg,png,gif,svg,webp}`], { events: ['all'], delay: 100 }, series(copyImg, reload));
watch([`${dir.blocks}sprite-svg/svg/*.svg`], { events: ['all'], delay: 100 }, series(generateSvgSprite, copyImg, reload));
watch([`${dir.blocks}sprite-png/png/*.png`], { events: ['all'], delay: 100 }, series(generatePngSprite, copyImg, compileSass));
} }
exports.default = series( exports.default = series(
parallel(clearBuildDir, writePugMixinsFile), parallel(clearBuildDir, writePugMixinsFile),
parallel(compilePugFast, copyAssets, copyImg), parallel(compilePugFast, copyAssets),
parallel(generateSvgSprite, generatePngSprite),
parallel(copyImg),
parallel(writeSassImportsFile, writeJsRequiresFile), parallel(writeSassImportsFile, writeJsRequiresFile),
parallel(compileSass, buildJs), parallel(compileSass, buildJs),
serve, serve,
...@@ -348,6 +396,11 @@ function getArraysDiff(a1, a2) { ...@@ -348,6 +396,11 @@ function getArraysDiff(a1, a2) {
return a1.filter(i=>!a2.includes(i)).concat(a2.filter(i=>!a1.includes(i))) return a1.filter(i=>!a2.includes(i)).concat(a2.filter(i=>!a1.includes(i)))
} }
/**
* Уникализация массива
* @param {array} arr Массив, в котором могут быть неуникальные элементы
* @return {array} Массив без повторов
*/
function uniqueArray(arr) { function uniqueArray(arr) {
var obj = {}; var obj = {};
for (var i = 0; i < arr.length; i++) { for (var i = 0; i < arr.length; i++) {
...@@ -387,6 +440,10 @@ function getClassesToBlocksList(file, enc, cb) { ...@@ -387,6 +440,10 @@ function getClassesToBlocksList(file, enc, cb) {
// Добавляем // Добавляем
blocksList.push(item); blocksList.push(item);
} }
// Добавим все обязательные блоки из настроек
config.alwaysAddBlocks.forEach(function(item) {
blocksList.push(item);
});
file.contents = new Buffer(fileContent); file.contents = new Buffer(fileContent);
} }
this.push(file); this.push(file);
......
Папка, в которую генерируется спрайт.
Папка, в которую генерируется спрайт.
require('svg4everybody');
svg4everybody(); svg4everybody();
Папка для исходников спрайта. Минимизация svg происходит в процессе сборки спрайта, иметь в этой папке минимизированные изображения не обязательно.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment