Commit 664308b1 authored by Nikolay Gromov's avatar Nikolay Gromov

Впилил JS и обработку статики

parent 26b76d69
...@@ -2,8 +2,9 @@ design/ ...@@ -2,8 +2,9 @@ design/
build/* build/*
!build/readme.md !build/readme.md
src/pug/mixins.pug src/pug/mixins.pug
src/js/entry.js
src/scss/style.scss src/scss/style.scss
src/blocks/sprite-svg/img/sprite-svg.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
......
# loglevel=silent
# Стартовый проект с gulp ![Test Status](https://travis-ci.org/nicothin/NTH-start-project.svg?branch=master) [![devDependencies Status](https://david-dm.org/nicothin/NTH-start-project/dev-status.svg)](https://david-dm.org/nicothin/NTH-start-project?type=dev) [![dependencies Status](https://david-dm.org/nicothin/NTH-start-project/status.svg)](https://david-dm.org/nicothin/NTH-start-project) # Стартовый проект с gulp ![Test Status](https://travis-ci.org/nicothin/NTH-start-project.svg?branch=master) [![devDependencies Status](https://david-dm.org/nicothin/NTH-start-project/dev-status.svg)](https://david-dm.org/nicothin/NTH-start-project?type=dev) [![dependencies Status](https://david-dm.org/nicothin/NTH-start-project/status.svg)](https://david-dm.org/nicothin/NTH-start-project)
## Сборка разметки из pug ## Структура проекта
Директории, содержащие какие-либо файлы с разметкой:
```bash ```bash
./src/ build/ # Папка сборки
src/
blocks/ # Блоки blocks/ # Блоки
some-block/ # Директория блока (все технологии блока, в т.ч. и pug) favicon/ # Фавиконки
some-block.pug # Разметка блока (pug-примесь!) fonts/ # Шрифты
img/ # Изображения, не принадлежащие ни одному БЭМ-блоку
pages/ # Страницы проекта pages/ # Страницы проекта
index.pug # Главная страница pug/ # Служебные pug-файлы (шаблоны, примеси)
pug/ # Служебные файлы (шаблоны, примеси) scss/ # Служебные стилевые файлы
layout.pug # Шаблон всех страниц
mixins.pug # Примеси (создаётся автоматически, инклудит ВСЕ блоки (из ./src/blocks/), имеющие одноимённый блоку pug-файл)
``` ```
## Как это работает ## Как это работает
При `npm start` (запускается дефотная задача gulp): При `npm start` (запускается дефолтная задача gulp):
1. Создаётся глобальная переменная `config` с настройками (из `./config.js`). 1. Создаётся глобальная переменная `config` с настройками (из `./config.js`).
2. Очищается папка сборки (`./build/`). 2. Очищается папка сборки (`./build/`).
3. Записывается файл `./src/pug/mixins.pug` (инклуды всех pug-файлов блоков, независимо от использования на проекте). Инклуд добавляется только если в папке блока есть одноимённый блоку pug-файл. 3. Записывается `./src/pug/mixins.pug` (инклуды всех pug-файлов блоков, независимо от использования на проекте). Инклуд добавляется только если в папке блока есть одноимённый блоку pug-файл.
3. Pug-файлы из `./src/pages/` компилируются в html и пишутся в `./build/`. **В процессе обновляется список блоков** (`config.blocks`), туда попадают все БЭМ-блоки из разметки страниц (кроме страниц из `config.notGetBlocks`), кроме исключений из `config.ignoredBlocks`. Если есть какие-то новые блоки, записывается файл `./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-файлы существуют в папках блоков).
- Импорты файлов из `config.addStyleAfter`. - Импорты файлов из `config.addStyleAfter`.
5. Записывается `./src/js/entry.js`, в котором:
- Подключения файлов из `config.addJsBefore`.
- Подключения js-файлов js-файлов БЭМ-блоков, использующихся на проекте (из `config.blocks`, но только если сами js-файлы существуют в папках блоков).
- Подключения файлов из `config.addJsAfter`.
6. Компилируется и обрабатывается PostCSS-ом Sass, собирается JS.
7. Копируются все статичные файлы (список в `config.copyAssets`).
998. Запускается слежение и сервер. 998. Запускается слежение и сервер.
999. PROFIT 999. PROFIT
......
...@@ -14,7 +14,9 @@ let config = ...@@ -14,7 +14,9 @@ let config =
"main-nav", "main-nav",
"burger", "burger",
"page-footer", "page-footer",
"some-new-class" "some-new-class",
"haters",
"haters2"
], ],
"addStyleBefore": [ "addStyleBefore": [
"./src/scss/functions.scss", "./src/scss/functions.scss",
...@@ -26,16 +28,17 @@ let config = ...@@ -26,16 +28,17 @@ let config =
], ],
"addJsBefore": [], "addJsBefore": [],
"addJsAfter": [ "addJsAfter": [
"./src/js/global-script.js" "./script.js"
], ],
"addImages": [], "addAssets": {
"addAssets": [], "./src/img/avatar-*": "img/",
"copiedCss": [], "./src/img/DSC_*": "img/",
"copiedJs": [], "./src/fonts/demo-empty-open-sans.woff2": "fonts/",
"./src/favicon/*.{png,ico,svg,xml,webmanifest}": "img/favicon"
},
"dir": { "dir": {
"src": "./src/", "src": "./src/",
"build": "./build/", "build": "./build/"
"blocks": "./src/blocks/"
} }
}; };
......
...@@ -16,6 +16,10 @@ const debug = require('gulp-debug'); ...@@ -16,6 +16,10 @@ const debug = require('gulp-debug');
const sass = require('gulp-sass'); const sass = require('gulp-sass');
const notify = require('gulp-notify'); const notify = require('gulp-notify');
const gulpIf = require('gulp-if'); const gulpIf = require('gulp-if');
const browserify = require('browserify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const postcss = require('gulp-postcss'); const postcss = require('gulp-postcss');
const autoprefixer = require("autoprefixer"); const autoprefixer = require("autoprefixer");
const mqpacker = require("css-mqpacker"); const mqpacker = require("css-mqpacker");
...@@ -23,11 +27,13 @@ const atImport = require("postcss-import"); ...@@ -23,11 +27,13 @@ const atImport = require("postcss-import");
const cleanss = require('gulp-cleancss'); 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');
// Настройки из файла // Настройки из файла
let config = require('./config.js'); let config = require('./config.js');
// Директории из настроек (dir.src = "./src/", dir.build = "./build/", dir.blocks = "./src/blocks/") // Директории из настроек (dir.src = "./src/", dir.build = "./build/")
let dir = config.dir; let dir = config.dir;
dir.blocks = `${dir.src}blocks/`;
// Список блоков, который будет получен из классов HTML после компиляции pug // Список блоков, который будет получен из классов HTML после компиляции pug
let blocksList = []; let blocksList = [];
// Старый список блоков в виде строки // Старый список блоков в виде строки
...@@ -37,7 +43,7 @@ let repoUrl = require('./package.json').repository.url.replace(/\.git$/g, ''); ...@@ -37,7 +43,7 @@ let repoUrl = require('./package.json').repository.url.replace(/\.git$/g, '');
// Определение: разработка это или финальная сборка // Определение: разработка это или финальная сборка
const isDev = !process.env.NODE_ENV || process.env.NODE_ENV == 'dev'; const isDev = !process.env.NODE_ENV || process.env.NODE_ENV == 'dev';
// Сообщение для компилируемых файлов // Сообщение для компилируемых файлов
let doNotEditMsg = '\n ВНИМАНИЕ! Этот файл генерируется автоматически.\n Любые изменения этого файла будут потеряны при следующей компиляции.\n Любое изменение проекта без возможности компиляции ДОЛЬШЕ И ДОРОЖЕ в 2-3 раза.\n\n'; let doNotEditMsg = '\n ВНИМАНИЕ! Этот файл генерируется автоматически.\n Любые изменения этого файла будут потеряны при следующей компиляции.\n Любое изменение проекта без возможности компиляции ДОЛЬШЕ И ДОРОЖЕ в 2-5 раза.\n\n';
// Настройки pug-компилятора // Настройки pug-компилятора
let pugOption = { let pugOption = {
data: { repoUrl: repoUrl, }, data: { repoUrl: repoUrl, },
...@@ -127,6 +133,72 @@ function writeSassImportsFile(cb) { ...@@ -127,6 +133,72 @@ function writeSassImportsFile(cb) {
exports.writeSassImportsFile = writeSassImportsFile; exports.writeSassImportsFile = writeSassImportsFile;
function buildJs() {
// var sourcemaps = require('gulp-sourcemaps');
return browserify({
entries: dir.src + '/js/entry.js',
debug: true
})
.transform('babelify', {presets: ['@babel/preset-env',]})
.bundle()
.pipe(source('bundle.js'))
.pipe(buffer())
// .pipe(sourcemaps.init({loadMaps: true}))
.pipe(gulpIf(!isDev, uglify()))
// .pipe(sourcemaps.write('./'))
.pipe(dest(dir.build + '/js'));
}
exports.buildJs = buildJs;
function writeJsRequiresFile(cb) {
// console.log( config.blocks );
let msg = `\n/*!*${doNotEditMsg.replace(/\n /gm,'\n * ').replace(/\n\n$/,'\n */\n\n')}`;
let jsRequires = msg;
config.addJsBefore.forEach(function(src) {
jsRequires += `require('${src}');\n`;
});
config.blocks.forEach(function(block) {
if(fileExist(`${dir.blocks}${block}/${block}.js`)) jsRequires += `require('../blocks/${block}/${block}.js');\n`;
});
config.addJsAfter.forEach(function(src) {
jsRequires += `require('${src}');\n`;
});
jsRequires += msg;
fs.writeFileSync(`${dir.src}js/entry.js`, jsRequires);
cb();
}
exports.writeJsRequiresFile = writeJsRequiresFile;
function copyAssets(cb) {
for (let item in config.addAssets) {
let dest = `${dir.build}${config.addAssets[item]}`;
(async () => {
await cpy(item, dest);
console.log(`---------- Скопировано: ${item} -> ${dest}`);
})();
}
cb();
}
exports.copyAssets = copyAssets;
function copyImg(cb) {
let copiedImages = [];
config.blocks.forEach(function(block) {
let src = `${dir.blocks}${block}/img`;
if(fileExist(src)) copiedImages.push(src);
});
(async () => {
await cpy(copiedImages, `${dir.build}img`);
console.log(`---------- Скопированы изображения БЭМ-блоков`);
})();
cb();
}
exports.copyImg = copyImg;
function clearBuildDir() { function clearBuildDir() {
return del([ return del([
`${dir.build}**/*`, `${dir.build}**/*`,
...@@ -148,9 +220,15 @@ function serve() { ...@@ -148,9 +220,15 @@ function serve() {
port: 8080, port: 8080,
startPath: 'index.html', startPath: 'index.html',
open: false, open: false,
notify: false,
}); });
// Файлы разметки страниц (изменение, добавление) // Файлы разметки страниц (изменение, добавление)
watch([`${dir.src}pages/**/*.pug`], { events: ['change', 'add'], delay: 100 }, series(compilePugFast, writeSassImportsFile, compileSass, reload)); watch([`${dir.src}pages/**/*.pug`], { events: ['change', 'add'], delay: 100 }, series(
compilePugFast,
parallel(writeSassImportsFile, writeJsRequiresFile),
parallel(compileSass, buildJs),
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) {
...@@ -161,24 +239,37 @@ function serve() { ...@@ -161,24 +239,37 @@ function serve() {
}); });
}); });
// Файлы разметки БЭМ-блоков (изменение, добавление) // Файлы разметки БЭМ-блоков (изменение, добавление)
watch([`${dir.blocks}**/*.pug`], { events: ['change', 'add'], delay: 100 }, series(compilePug, writeSassImportsFile, compileSass, reload)); watch([`${dir.blocks}**/*.pug`], { events: ['change', 'add'], delay: 100 }, series(
compilePug,
writeSassImportsFile,
compileSass,
reload
));
// Файлы разметки БЭМ-блоков (удаление) // Файлы разметки БЭМ-блоков (удаление)
watch([`${dir.blocks}**/*.pug`], { events: ['unlink'], delay: 100 }, series(writePugMixinsFile)); watch([`${dir.blocks}**/*.pug`], { events: ['unlink'], delay: 100 }, series(writePugMixinsFile));
// Глобальные pug-файлы, кроме файла примесей (все события) // Глобальные pug-файлы, кроме файла примесей (все события)
watch([`${dir.src}pug/**/*.pug`, `!${dir.src}pug/mixins.pug`], { delay: 100 }, series(compilePug, writeSassImportsFile, compileSass, reload)); watch([`${dir.src}pug/**/*.pug`, `!${dir.src}pug/mixins.pug`], { delay: 100 }, series(
compilePugFast,
parallel(writeSassImportsFile, writeJsRequiresFile),
parallel(compileSass, buildJs),
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.blocks}**/img/*.{jpg,jpeg,png,gif,svg,webp}`], { events: ['all'], delay: 100 }, series(copyImg, reload));
} }
// exports.serve = serve;
exports.default = series( exports.default = series(
parallel(clearBuildDir, writePugMixinsFile), parallel(clearBuildDir, writePugMixinsFile),
compilePugFast, parallel(compilePugFast, copyAssets, copyImg),
writeSassImportsFile, parallel(writeSassImportsFile, writeJsRequiresFile),
compileSass, parallel(compileSass, buildJs),
serve, serve,
); );
......
...@@ -32,35 +32,33 @@ ...@@ -32,35 +32,33 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.1.6", "@babel/core": "^7.1.6",
"@babel/preset-env": "^7.1.6", "@babel/preset-env": "^7.1.6",
"@htmlacademy/editorconfig-cli": "^1.0.0",
"autoprefixer": "^9.3.1",
"babelify": "^10.0.0", "babelify": "^10.0.0",
"browser-sync": "^2.18.8", "browser-sync": "^2.18.8",
"browserify": "^16.2.3", "browserify": "^16.2.3",
"cpy": "^7.0.1",
"cross-env": "^5.0.0", "cross-env": "^5.0.0",
"gulp": "^4.0.0", "css-mqpacker": "^7.0.0",
"del": "^3.0.0", "del": "^3.0.0",
"get-classes-from-html": "^1.0.1", "get-classes-from-html": "^1.0.1",
"gulp-pug": "^4.0.1",
"gulp-html-beautify": "^1.0.1",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"through2": "^3.0.0",
"json-format": "^1.0.1",
"husky": "^1.1.4",
"autoprefixer": "^9.3.1",
"css-mqpacker": "^7.0.0",
"@htmlacademy/editorconfig-cli": "^1.0.0",
"gh-pages": "^2.0.1", "gh-pages": "^2.0.1",
"gulp": "^4.0.0",
"gulp-cheerio": "^0.6.2", "gulp-cheerio": "^0.6.2",
"gulp-cleancss": "^0.2.2", "gulp-cleancss": "^0.2.2",
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"gulp-debug": "^4.0.0", "gulp-debug": "^4.0.0",
"gulp-html-beautify": "^1.0.1",
"gulp-if": "^2.0.2", "gulp-if": "^2.0.2",
"gulp-imagemin": "^5.0.3", "gulp-imagemin": "^5.0.3",
"gulp-insert": "^0.5.0", "gulp-insert": "^0.5.0",
"gulp-newer": "^1.3.0", "gulp-newer": "^1.3.0",
"gulp-notify": "^3.0.0", "gulp-notify": "^3.0.0",
"gulp-plumber": "^1.1.0",
"gulp-postcss": "^8.0.0", "gulp-postcss": "^8.0.0",
"gulp-pug": "^4.0.1",
"gulp-pug-lint": "git+https://github.com/nicothin/gulp-pug-lint.git", "gulp-pug-lint": "git+https://github.com/nicothin/gulp-pug-lint.git",
"gulp-rename": "^1.2.2",
"gulp-replace": "^1.0.0", "gulp-replace": "^1.0.0",
"gulp-sass": "^4.0.1", "gulp-sass": "^4.0.1",
"gulp-size": "^3.0.0", "gulp-size": "^3.0.0",
...@@ -70,6 +68,8 @@ ...@@ -70,6 +68,8 @@
"gulp-uglify": "^3.0.0", "gulp-uglify": "^3.0.0",
"gulp-wait": "0.0.2", "gulp-wait": "0.0.2",
"gulp.spritesmith": "^6.3.0", "gulp.spritesmith": "^6.3.0",
"husky": "^1.1.4",
"json-format": "^1.0.1",
"jstransformer-markdown-it": "^2.0.0", "jstransformer-markdown-it": "^2.0.0",
"lint-staged": "^8.0.4", "lint-staged": "^8.0.4",
"merge-stream": "^1.0.1", "merge-stream": "^1.0.1",
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
"postcss-inline-svg": "^3.0.0", "postcss-inline-svg": "^3.0.0",
"postcss-object-fit-images": "^1.1.2", "postcss-object-fit-images": "^1.1.2",
"stylelint": "^9.1.1", "stylelint": "^9.1.1",
"through2": "^3.0.0",
"vinyl-buffer": "^1.0.1", "vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0" "vinyl-source-stream": "^2.0.0"
}, },
......
Дополнительные CSS-файлы, которые отчего-то, «не тянут» на полноценные БЭМ-блоки.
Укажите эти файлы в `package.json` для попадания их в обработку (см. `./README.md`).
Шрифты проекта. Будут автоматически скопированы в папку сборки.
Какие-то общие изображения проекта (контентные, к примеру).
Укажите эту папку в `package.json` для попадания графических файлов в обработку (см. `./README.md`).
Дополнительные js-файлы, которые отчего-то, «не тянут» на полноценные БЭМ-блоки.
Укажите эти файлы в `package.json` для попадания их в обработку (см. `./README.md`).
// Если на проекте jQuery // Если на проекте jQuery
// var $ = require('jquery');
// $( document ).ready(function() { // $( document ).ready(function() {
// // code // // code
// }); // });
......
...@@ -108,8 +108,8 @@ block content ...@@ -108,8 +108,8 @@ block content
code </body> code </body>
code </html> code </html>
+block-lib('typo', 'Текст, теги', false) //- +block-lib('typo', 'Текст, теги', false)
include:markdown-it(html='true') ../blocks/typo/readme.md //- include:markdown-it(html='true') ../blocks/typo/readme.md
+block-lib('grid-mixins', 'Примеси-генераторы модульной сетки', false, 'grid') +block-lib('grid-mixins', 'Примеси-генераторы модульной сетки', false, 'grid')
:markdown-it() :markdown-it()
......
extends ../pug/layout.pug
block meta
title Главная
meta(name='description', content='')
//- block append head
//- link(rel='stylesheet', href='css/some.css')
block header
+page-header()
+logo('/')
span Логотип
+main-nav('10')
.some-new-class Class
.some-new-class__eee EEE!
.some-new-class.some-new-class--error Class
.some-new-class__eee EEE!
block content
p Содержимое. #[a(href='blocks-demo.html') Библиотека блоков].
block footer
+page-footer()
p «Подвал»
p Контактный телефон: #[a(href="tel:+70000000000") +7 000 000 00 00]
//- block page-bottom
//- script(src='js/some.js')
...@@ -10,7 +10,7 @@ block meta ...@@ -10,7 +10,7 @@ block meta
block header block header
+page-header() +page-header()
+logo('/') +logo('/')
span Логотип 1 span Логотип
+main-nav('10') +main-nav('10')
block content block content
......
...@@ -49,4 +49,4 @@ html(class='no-js page', lang='ru') ...@@ -49,4 +49,4 @@ html(class='no-js page', lang='ru')
p «подвал» p «подвал»
block page-bottom block page-bottom
script(src='js/script.min.js') script(src='js/bundle.js')
`style.scss` генерируется автоматически, не пишите туда ничего. `style.scss` генерируется автоматически, не пишите туда ничего.
Прочие файлы игнорируются, если не упомянуты в `./projectConfig.json` (см. `./README.md`).
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