Commit 1b7eb1f3 authored by Nikolay Gromov's avatar Nikolay Gromov

Merging

parents 21d475ba b6ffb269
...@@ -30,15 +30,7 @@ ...@@ -30,15 +30,7 @@
</tr> </tr>
<tr> <tr>
<td><code>npm run deploy</code></td> <td><code>npm run deploy</code></td>
<td>Отправка содержимого папки сборки на GH-pages (для корректного сообщения адреса просмотра введите его в <code>package.json</code>)</td> <td>Сборка проекта без карт кода и отправка содержимого папки сборки на GH-pages (для корректного сообщения адреса просмотра введите его в <code>./package.json</code>)</td>
</tr>
<tr>
<td><code>npm test</code></td>
<td>Тестирование stylelint-ом.</td>
</tr>
<tr>
<td><code>NODE_ENV=production npm start</code></td>
<td>Сборка проекта без карт кода с минификацией.</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
...@@ -48,17 +40,17 @@ ...@@ -48,17 +40,17 @@
## Парадигма ## Парадигма
- Используется именование классов, файлов и переменных по БЭМ. - Используется именование классов, файлов и переменных по БЭМ.
- Каждый БЭМ-блок в своей папке внутри `/src/blocks/` (less, js, картинки, разметка; обязателен только less-файл). - Список использованных в проекте БЭМ-блоков и оп. файлов указан в `./package.json`.
- Есть глобальные файлы: css, js, шрифты, картинки, less-файлы (переменные, глобальная стилизация). - Каждый БЭМ-блок в своей папке внутри `./src/blocks/` (стили, js, картинки, разметка; обязателен только стилевой файл).
- Есть диспетчер подключений `/src/less/style.less`, если в нем импортирован less-файл какого-либо блока, этот блок считается используемым (обрабатывается его js и доп. файлы). - Есть глобальные файлы: стилевые, js, шрифты, картинки.
- Диспетчер подключения стилей `./src/scss/style.scss` генерируется автоматически при старте любой gulp-задачи.
- Для разметки можно использовать [микрошаблонизацию](https://www.npmjs.com/package/gulp-file-include). А можно и не использовать. - Для разметки можно использовать [микрошаблонизацию](https://www.npmjs.com/package/gulp-file-include). А можно и не использовать.
- **Перед коммитом происходит проверка `.less`-файлов** на соответствие правилам Stylelint (см. `.stylelintrc` в корне проекта). Если выявлены ошибки, коммит не будет создан.
### Блоки ### Блоки
Каждый блок лежит в `/src/blocks/` в своей папке. Каждый блок — как минимум, папка и одноимённый less-файл. Каждый блок лежит в `./src/blocks/` в своей папке. Каждый блок — как минимум, папка и одноимённый scss-файл.
Возможное содержимое блока: Возможное содержимое блока:
...@@ -66,59 +58,81 @@ ...@@ -66,59 +58,81 @@
demo-block/ # Папка блока demo-block/ # Папка блока
img/ # Изображения, используемые блоком и обрабатываемые автоматикой сборки img/ # Изображения, используемые блоком и обрабатываемые автоматикой сборки
some-folder/ # Какая-то сторонняя папка, не обрабатываемые автоматикой some-folder/ # Какая-то сторонняя папка, не обрабатываемые автоматикой
demo-block.less # Главный стилевой файл блока demo-block.scss # Главный стилевой файл блока
demo-block--mod.less # Отдельный файл БЭМ-модификатора блока demo-block--mod.scss # Отдельный файл БЭМ-модификатора блока
demo-block.js # Главный js-файл блока demo-block.js # Главный js-файл блока
demo-block--mod.js # js-файл для отдельного БЭМ-модификатора блока demo-block--mod.js # js-файл для отдельного БЭМ-модификатора блока
demo-block.html # Варианты разметки (как документация блока или как вставляемый микрошаблонизатором фрагмент) demo-block.html # Варианты разметки (как документация блока или как вставляемый микрошаблонизатором фрагмент)
demo-block.css # Добавочный css (копируется как отдельный файл в `build/css`)
readme.md # Какое-то пояснение readme.md # Какое-то пояснение
``` ```
### Удобное создание нового блока ### Удобное создание нового блока
```bash ```bash
# формат: node createBlock.js [имя блока] [доп. расширения через пробел] # формат: node createBlock.js [имя блока] [доп. расширения через пробел]
node createBlock.js block # создаст только папку блока, block.html и block.less node createBlock.js block # создаст только папку блока, block.html и block.scss
node createBlock.js new-block js jade # создаст папку блока, new-block.html, new-block.less, new-block.js, new-block.jade node createBlock.js new-block js pug # создаст папку блока, new-block.html, new-block.scss, new-block.js, new-block.pug
node createBlock.js new-block js img # создаст папку блока, new-block.html, new-block.less, new-block.js, подпапку img/ node createBlock.js new-block js img # создаст папку блока, new-block.html, new-block.scss, new-block.js, подпапку img/
``` ```
По умолчанию будут созданы `.html` и `.less` файлы, в них будет записан стартовый контент.
Если блок уже существует, файлы не будут затёрты, но создадутся те файлы, которые ещё не существуют. Если блок уже существует, файлы не будут затёрты, но создадутся те файлы, которые ещё не существуют.
После создания блока, в диспетчер подключений будет дописана (в самый низ) строка импорта стилевого файла.
## Подключение блоков ## Подключение блоков
Если в диспетчере подключений (файле `./src/less/style.less`): Настройки подключаемых файлов указаны в `./package.json`, в секции `configProject`:
```less ```json
@import './src/blocks/demo-block/demo-block.less'; "blocks": {
"page-header": [],
"page-footer": [
"__extra-element",
"--extra-modifier"
]
},
"addCssBefore": [
"./src/scss/variables.scss"
],
"addCssAfter": [
"./src/scss/print.scss"
],
"addJsBefore": [
"./src/js/jquery.3.1.1.min.js"
],
"addJsAfter": [
"./src/js/global-script.js"
],
"addImages": [
"./src/img/"
],
``` ```
То указанный файл будет взят в компиляцию стилей, а так же: При указанной записи в обработку будут взяты следующие папки и файлы (в указанной последовательности):
- в обработку будет взят js-файл блока: `./src/blocks/demo-block/demo-block.js` (если существует и не пустой, будет конкатенирован с прочими js-файлами и углифицирован)
- в обработку будет взят css-файл блока: `./src/blocks/demo-block/demo-block.css` (если существует и не пустой, будет скопирован в папку сборки и минифицирован)
- в обработку будут добавлены все картинки блока: `./src/blocks/demo-block/img/*.{jpg,jpeg,gif,png,svg}` (если в папке блока существует подпапка `img/`)
Если в диспетчере подключений:
```bash
css:
[ './src/scss/variables.scss',
'./src/blocks/page-header/page-header.scss',
'./src/blocks/page-footer/page-footer.scss',
'./src/blocks/page-footer/page-footer__extra-element.scss',
'./src/blocks/page-footer/page-footer--extra-modifier.scss',
'./src/scss/print.scss' ],
js:
[ './src/js/jquery.3.1.1.min.js',
'./src/blocks/page-header/page-header.js',
'./src/blocks/page-footer/page-footer.js',
'./src/blocks/page-footer/page-footer__extra-element.js',
'./src/blocks/page-footer/page-footer--extra-modifier.js',
'./src/js/global-script.js' ],
img:
[ './src/img/',
'./src/blocks/page-header/img',
'./src/blocks/page-footer/img' ]
``` ```
@import './src/blocks/demo-block/demo-block.less';
@import './src/blocks/demo-block/demo-block--mod.less';
```
То указанные файлы будет взяты в компиляцию стилей, а так же:
- в обработку будет взят js-файл блока: `./src/blocks/demo-block/demo-block.js` (если существует и не пустой, будет конкатенирован с прочими js-файлами и углифицирован)
- в обработку будет взят js-файл блока: `./src/blocks/demo-block/demo-block--mod.js` (если существует и не пустой, будет конкатенирован с прочими js-файлами и углифицирован)
- в обработку будет взят css-файл блока: `./src/blocks/demo-block/demo-block.css` (если существует и не пустой, будет скопирован в папку сборки и минифицирован)
- в обработку будет взят css-файл блока: `./src/blocks/demo-block/demo-block--mod.css` (если существует и не пустой, будет скопирован в папку сборки и минифицирован)
- в обработку будут добавлены все картинки блока: `./src/blocks/demo-block/img/*.{jpg,jpeg,gif,png,svg}` (если в папке блока существует подпапка `img/`)
...@@ -129,11 +143,10 @@ build/ # Сюда собирается проект, здесь раб ...@@ -129,11 +143,10 @@ build/ # Сюда собирается проект, здесь раб
src/ # Исходные файлы src/ # Исходные файлы
_include/ # - фрагменты html для самого верха (секция head) и самого низа (перед закрывающим body) страницы _include/ # - фрагменты html для самого верха (секция head) и самого низа (перед закрывающим body) страницы
blocks/ # - блоки (компоненты) проекта blocks/ # - блоки (компоненты) проекта
css/ # - глобальные css-файлы (будут скопированы только если существует и не пустые) css/ # - можно положить добавочные css-файлы
fonts/ # - шрифты проекта (будут скопированы в папку сборки, подпапку fonts/) img/ # - можно положить добавочные картинки
img/ # - глобальные картинки (будут обработаны только из корня этой папки, подпапки игнорируются) js/ # - можно положить добавочные js-файлы
js/ # - глобальный js-файл (обработается только если существует и не пустой), фреймворки (только копируются, могут быть подключены вручную) scss/ # - папка с диспетчером подключений стилей и глобальными файлами
less/ # - диспетчер подключений и глобальные стили
index.html # - главная страница проекта index.html # - главная страница проекта
``` ```
...@@ -141,4 +154,4 @@ src/ # Исходные файлы ...@@ -141,4 +154,4 @@ src/ # Исходные файлы
## Комментирование для разработчиков ## Комментирование для разработчиков
Для разметочных файлов можно использовать комментарии вида `<!--DEV Комментарий -->` — такие комментарии не попадут в собранный html. Для html-файлов можно использовать комментарии вида `<!--DEV Комментарий -->` — такие комментарии не попадут в собранный html.
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
const fs = require('fs'); const fs = require('fs');
const gulp = require('gulp'); const gulp = require('gulp');
const gulpSequence = require('gulp-sequence'); const gulpSequence = require('gulp-sequence');
const sass = require('gulp-sass');
const postcss = require('gulp-postcss'); const postcss = require('gulp-postcss');
const atImport = require("postcss-import")
const customProperties = require("postcss-custom-properties")
const autoprefixer = require("autoprefixer") const autoprefixer = require("autoprefixer")
const mqpacker = require("css-mqpacker")
const notify = require('gulp-notify'); const notify = require('gulp-notify');
const gulpIf = require('gulp-if'); const gulpIf = require('gulp-if');
const debug = require('gulp-debug'); const debug = require('gulp-debug');
...@@ -21,15 +21,15 @@ const del = require('del'); ...@@ -21,15 +21,15 @@ const del = require('del');
let pjson = require('./package.json'); let pjson = require('./package.json');
let dirs = pjson.configProject.dirs; let dirs = pjson.configProject.dirs;
let lists = getFilesList(pjson.configProject); let lists = getFilesList(pjson.configProject);
console.log('---------- Файлы и папки, взятые в работу:'); // console.log('---------- Файлы и папки, взятые в работу:');
console.log(lists); console.log(lists);
// Запишем стилевой файл диспетчер подключений // Запишем стилевой файл диспетчер подключений
let styleImports = ''; let styleImports = '/**\n * ВНИМАНИЕ! Этот файл генерируется автоматически.\n * Не пишите сюда ничего вручную, все такие правки будут потеряны.\n * Читайте ./README.md для понимания.\n */\n\n';
lists.css.forEach(function(blockPath) { lists.css.forEach(function(blockPath) {
styleImports += '@import url('+blockPath+');\n'; styleImports += '@import "'+blockPath+'";\n';
}); });
fs.writeFileSync('./src/css/style.css', styleImports); fs.writeFileSync('./src/scss/style.scss', styleImports);
// Запуск `NODE_ENV=production npm start [задача]` приведет к сборке без sourcemaps // Запуск `NODE_ENV=production npm start [задача]` приведет к сборке без sourcemaps
const isDev = !process.env.NODE_ENV || process.env.NODE_ENV == 'dev'; const isDev = !process.env.NODE_ENV || process.env.NODE_ENV == 'dev';
...@@ -46,16 +46,15 @@ gulp.task('clean', function () { ...@@ -46,16 +46,15 @@ gulp.task('clean', function () {
// Компиляция стилей // Компиляция стилей
gulp.task('style', function () { gulp.task('style', function () {
console.log('---------- Компиляция стилей'); console.log('---------- Компиляция стилей');
return gulp.src('./src/css/style.css') return gulp.src(dirs.srcPath + 'scss/style.scss')
.pipe(gulpIf(isDev, sourcemaps.init())) .pipe(gulpIf(isDev, sourcemaps.init()))
.pipe(debug({title: "Style:"})) .pipe(debug({title: "Style:"}))
.pipe(sass())
.pipe(postcss([ .pipe(postcss([
// customProperties({preserve: true}),
atImport({resolve: function(id, basedir, importOptions){return basedir+id.replace(/^\.\/src\/css/,'');}}),
autoprefixer({browsers: ['last 2 version']}), autoprefixer({browsers: ['last 2 version']}),
// mqpacker({ mqpacker({
// sort: true sort: true
// }), }),
])) ]))
.on('error', notify.onError(function(err){ .on('error', notify.onError(function(err){
return { return {
...@@ -75,6 +74,8 @@ gulp.task('style', function () { ...@@ -75,6 +74,8 @@ gulp.task('style', function () {
// .pipe(browserSync.stream()); // .pipe(browserSync.stream());
}); });
/** /**
* Вернет объект с обрабатываемыми файлами и папками * Вернет объект с обрабатываемыми файлами и папками
* @param {object} * @param {object}
...@@ -88,12 +89,12 @@ function getFilesList(config){ ...@@ -88,12 +89,12 @@ function getFilesList(config){
'img': [], 'img': [],
}; };
// CSS // Style
for (let blockName in config.blocks) { for (let blockName in config.blocks) {
res.css.push(config.dirs.srcPath + config.dirs.blocksDirName + '/' + blockName + '/' + blockName + '.css'); res.css.push(config.dirs.srcPath + config.dirs.blocksDirName + '/' + blockName + '/' + blockName + '.scss');
if(config.blocks[blockName].length) { if(config.blocks[blockName].length) {
config.blocks[blockName].forEach(function(elementName) { config.blocks[blockName].forEach(function(elementName) {
res.css.push(config.dirs.srcPath + config.dirs.blocksDirName + '/' + blockName + '/' + blockName + elementName + '.css'); res.css.push(config.dirs.srcPath + config.dirs.blocksDirName + '/' + blockName + '/' + blockName + elementName + '.scss');
}); });
} }
} }
......
...@@ -11,16 +11,13 @@ ...@@ -11,16 +11,13 @@
"configProject": { "configProject": {
"blocks": { "blocks": {
"page-header": [], "page-header": [],
"page-footer": [ "page-footer": []
"__inner",
"--some-mod"
]
}, },
"addCssBefore": [ "addCssBefore": [
"./src/css/variables.css" "./src/scss/variables.scss"
], ],
"addCssAfter": [ "addCssAfter": [
"./src/css/print.css" "./src/scss/print.scss"
], ],
"addJsBefore": [ "addJsBefore": [
"./src/js/jquery.3.1.1.min.js" "./src/js/jquery.3.1.1.min.js"
...@@ -38,13 +35,15 @@ ...@@ -38,13 +35,15 @@
} }
}, },
"scripts": { "scripts": {
"test": "stylelint \"src/**/*.less\"", "test": "stylelint \"src/**/*.scss\"",
"start": "gulp", "start": "gulp",
"deploy": "cross-env NODE_ENV=production ./node_modules/.bin/gulp build && cross-env ./node_modules/.bin/gulp deploy", "deploy": "cross-env NODE_ENV=production ./node_modules/.bin/gulp build && cross-env ./node_modules/.bin/gulp deploy",
"build": "cross-env NODE_ENV=production npm start build" "build": "cross-env NODE_ENV=production npm start build"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "^6.7.7", "autoprefixer": "^6.7.7",
"cross-env": "^3.2.4",
"css-mqpacker": "^5.0.1",
"del": "^2.2.2", "del": "^2.2.2",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-cleancss": "^0.2.2", "gulp-cleancss": "^0.2.2",
...@@ -53,10 +52,9 @@ ...@@ -53,10 +52,9 @@
"gulp-notify": "^3.0.0", "gulp-notify": "^3.0.0",
"gulp-postcss": "^6.3.0", "gulp-postcss": "^6.3.0",
"gulp-rename": "^1.2.2", "gulp-rename": "^1.2.2",
"gulp-sass": "^3.1.0",
"gulp-sequence": "^0.4.6", "gulp-sequence": "^0.4.6",
"gulp-size": "^2.1.0", "gulp-size": "^2.1.0",
"gulp-sourcemaps": "^2.4.1", "gulp-sourcemaps": "^2.4.1"
"postcss-custom-properties": "^5.0.2",
"postcss-import": "^9.1.0"
} }
} }
// Для импорта в диспетчер подключений: @import './src/blocks/page-footer/page-footer.less';
@import '../../less/variables.less'; // только для удобства обращения к переменным
.page-footer {
}
# Font Squirrel Font-face Generator Configuration File
# Upload this file to the generator to recreate the settings
# you used to create these fonts.
{"mode":"expert","formats":["woff"],"tt_instructor":"default","fix_gasp":"xy","fix_vertical_metrics":"Y","metrics_ascent":"","metrics_descent":"","metrics_linegap":"","add_spaces":"Y","add_hyphens":"Y","fallback":"none","fallback_custom":"100","options_subset":"advanced","subset_custom":"!\"#$%&'()*+,-.\/0123456789:;<=>?@ABCDEFGH IJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u00a8\u00a9\u00ab\u00ae\u00b4\u00b8\u00bb\u02c6\u02da\u02dc\u0401\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0451","subset_custom_range":"","subset_ot_features_list":"","base64":"Y","css_stylesheet":"font.css","filename_suffix":"","emsquare":"2048","spacing_adjustment":"0","rememberme":"Y"}
\ No newline at end of file
Файлы шрифтов из этой папки копируются в папку сборки.
Предпочтительно использовать [fontsquirell](http://www.fontsquirrel.com/tools/webfont-generator) или [jaicab.com/localFont/](http://jaicab.com/localFont/) для создания CSS со шрифтами.
Символы, которые имеет смысл брать в шрифт:
` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¢£¥¨©«®´¸»ˆ˚˜ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё‐‑‒–—―‘’‚“”„…‰‹›€™`
Приложен файл конфигурации для [fontsquirrel.com](http://www.fontsquirrel.com/tools/webfont-generator)
@media print {
*,
*:before,
*:after {
background: transparent !important;
color: #000 !important;
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline !important;
}
a[href]:after {
content: ' (' attr(href) ')';
}
abbr[title]:after {
content: ' (' attr(title) ')';
}
a[href^='#']:after,
a[href^='javascript:']:after {
content: '';
}
pre,
blockquote {
border: 1px solid #999 !important;
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
table {
border-collapse: collapse !important;
td,
th {
background-color: #fff !important;
}
}
}
/**
* ВНИМАНИЕ! Этот файл генерируется автоматически.
* Не пишите сюда ничего вручную, все такие правки будут потеряны.
* Читайте ./README.md для понимания.
*/
// Базовые цвета https://colorscheme.ru/color-converter.html
$black: hsl(0, 0%, 0%);
$gray-darkest: hsl(0, 0%, 10%);
$gray-darker: hsl(0, 0%, 20%);
$gray-darken: hsl(0, 0%, 30%);
$gray-dark: hsl(0, 0%, 40%);
$gray: hsl(0, 0%, 50%);
$gray-light: hsl(0, 0%, 60%);
$gray-lighten: hsl(0, 0%, 70%);
$gray-lighter: hsl(0, 0%, 80%);
$gray-lightest: hsl(0, 0%, 90%);
$white: hsl(0, 0%, 100%);
$color-main: hsl(208, 98%, 43%);
$color-success: hsl(120, 39%, 54%);
$color-danger: hsl(2, 64%, 58%);
// Семантические цвета
$text-color: $gray-darkest;
$text-color--muted: $gray;
$body-bg: #fff;
$link-color: $color-main;
$link-color--hover: darken($color-main, 15%);
$border-color: $gray-light;
// Базовая типографика
$font-size: 14px;
$font-size--h1: 2.25em;
$font-size--h2: 1.875em;
$font-size--h3: 1.5em;
$font-size--h4: 1.25em;
$font-size--h5: 1em;
$font-size--h6: 1em;
$font-size--small: 0.75em;
$line-height: 1.375;
$font-family: -apple-system, BlinkMacSystemFont, 'Roboto', 'Ubuntu', 'Droid Sans', 'Helvetica Neue', 'Arial', sans-serif;
$font-family--serif: 'Georgia', 'Times New Roman', 'Times', serif;
$font-family--monospace: 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', monospace;
$font-family--headings: $font-family;
// Ширины
$screen-xs: 0;
$screen-sm: 480px;
$screen-md: 768px;
$screen-lg: 992px;
$screen-xl: 1200px;
$screen-xxl: 1800px;
$container-sm: 100%;
$container-md: 100%;
$container-lg: $screen-lg - 30;
$container-xl: $screen-xl - 30;
$container-xxl: $screen-xxl - 30;
// Модульная сетка
$grid-columns: 12;
$grid-gutter-width: 30px;
// Разное
$border-radius: 3px;
$opacity: 0.7;
$transition-time: 0.3s;
$shadow: 0 4px 2px -2px rgba(0, 0, 0, 0.3);
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