Commit 94dc6934 authored by Nikolay Gromov's avatar Nikolay Gromov

Допил автоматизации

parent 749816e5
# перечисление игнорируемых stylelint-ом файлов
...@@ -2,14 +2,18 @@ ...@@ -2,14 +2,18 @@
ВНИМАНИЕ! Этот проект в разработке (призван систематизировать мои личные наработки из области вёрстки), я добавляю и меняю в нем довольно много всего. Это даже не альфа. Периодически может выглядеть странно и не менее странно работать. ВНИМАНИЕ! Этот проект в разработке (призван систематизировать мои личные наработки из области вёрстки), я добавляю и меняю в нем довольно много всего. Это даже не альфа. Периодически может выглядеть странно и не менее странно работать.
Установка: выполнить в папке проекта: `npm i`. Установка: `npm i`.
Использование: `npm start` (дабы не ставить глобально 4-ю версию gulp, которая сейчас в альфе). После `npm start` можно через пробел указать задачу. К примеру `npm start less` выполнит только задачу `less` из `gulpfile.js` (полный список задач смотри в `gulpfile.js`). Использование: `npm start`. После `npm start` можно через пробел указать задачу. К примеру `npm start less` выполнит только задачу `less` из `gulpfile.js` (полный список задач смотри в `gulpfile.js`).
`port=3004 npm start` — для запуска сервера автообновлений на указанном порту.
`npm run build` — сборка проекта без карт кода (минифицированный вид, как результат работы). `npm run build` — сборка проекта без карт кода (минифицированный вид, как результат работы).
`npm run deploy` — сборка проекта без карт кода и отправка содержимого папки сборки на GH-pages (для корректного сообщения адреса просмотра введите его в `package.json`).
`npm test` — запуск проверки `.less`-файлов Stylelint-ом.
`port=3004 npm start` — для запуска сервера автообновлений на указанном порту.
## Парадигма ## Парадигма
...@@ -19,6 +23,7 @@ ...@@ -19,6 +23,7 @@
- Есть глобальные файлы: css, js, шрифты, картинки, less-файлы (переменные, глобальная стилизация...). - Есть глобальные файлы: css, js, шрифты, картинки, less-файлы (переменные, глобальная стилизация...).
- Есть диспетчер подключений `/src/less/style.less`. Если в нем импортирован less-файл какого-либо блока, этот блок считается используемым (обрабатывается его js и доп. файлы). - Есть диспетчер подключений `/src/less/style.less`. Если в нем импортирован less-файл какого-либо блока, этот блок считается используемым (обрабатывается его js и доп. файлы).
- Для разметки можно использовать [микрошаблонизацию](https://www.npmjs.com/package/gulp-file-include) — обычное включение разметки мелких файлов внутрь больших файлов с возможностью передавать какие-то данные в мелкие файлы. А можно и не использовать. - Для разметки можно использовать [микрошаблонизацию](https://www.npmjs.com/package/gulp-file-include) — обычное включение разметки мелких файлов внутрь больших файлов с возможностью передавать какие-то данные в мелкие файлы. А можно и не использовать.
- **Перед коммитом происходит проверка `.less`-файлов** на соответствие правилам Stylelint (см. `.stylelintrc` в корне проекта). Если выявлены ошибки, коммит не будет создан, нужно исправить ошибки, переиндексировать файлы и сделать коммит.
...@@ -31,14 +36,13 @@ ...@@ -31,14 +36,13 @@
```bash ```bash
demo-block/ # Папка блока demo-block/ # Папка блока
img/ # Изображения, используемые блоком и обрабатываемые автоматикой сборки img/ # Изображения, используемые блоком и обрабатываемые автоматикой сборки
img_to_bg/ # Изображения, не обрабатываемые автоматикой сборки (имя папки — любое, обрабатываются только изображения из папки img/ внутри папки блока (см. предыдущую строку) some-folder/ # Какая-то сторонняя папка, не обрабатываемые автоматикой
demo-block.less # Главный стилевой файл блока demo-block.less # Главный стилевой файл блока
demo-block--mod.less # Отдельный файл модификатора блока (если объемный и нужен не на всех проектах) demo-block--mod.less # Отдельный файл БЭМ-модификатора блока
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`) demo-block.css # Добавочный css (копируется как отдельный файл в `build/css`)
library.js # Дополнительная js-библиотека, берется в конкатенируемый js-файл проекта (имя любое, в конкатенацию берется перед всеми прочими файлами, повторения ищутся по имени файла)
readme.md # Какое-то пояснение readme.md # Какое-то пояснение
``` ```
...@@ -47,8 +51,9 @@ demo-block/ # Папка блока ...@@ -47,8 +51,9 @@ demo-block/ # Папка блока
```bash ```bash
# формат: node createBlock.js [имя блока] [доп. расширения через пробел] # формат: node createBlock.js [имя блока] [доп. расширения через пробел]
node createBlock.js block # создаст только папку, block.html и block.less node createBlock.js block # создаст только папку блока, block.html и block.less
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 jade # создаст папку блока, new-block.html, new-block.less, new-block.js, new-block.jade
node createBlock.js new-block js img # создаст папку блока, new-block.html, new-block.less, new-block.js, подпапку img/
``` ```
По умолчанию будут созданы `.html` и `.less` файлы, в них будет записан стартовый контент. По умолчанию будут созданы `.html` и `.less` файлы, в них будет записан стартовый контент.
...@@ -61,9 +66,9 @@ node createBlock.js new-block js jade # создаст папку, new-block.htm ...@@ -61,9 +66,9 @@ node createBlock.js new-block js jade # создаст папку, new-block.htm
## Подключение блоков ## Подключение блоков
Если в диспетчере подключений (`./src/less/style.less`): Если в диспетчере подключений (файле `./src/less/style.less`):
``` ```less
@import './src/blocks/demo-block/demo-block.less'; @import './src/blocks/demo-block/demo-block.less';
``` ```
...@@ -95,8 +100,8 @@ build/ # Сюда собирается проект, здесь раб ...@@ -95,8 +100,8 @@ build/ # Сюда собирается проект, здесь раб
src/ # Исходные файлы src/ # Исходные файлы
_include/ # - фрагменты html для самого верха (секция head) и самого низа (перед закрывающим body) страницы _include/ # - фрагменты html для самого верха (секция head) и самого низа (перед закрывающим body) страницы
blocks/ # - блоки (компоненты) проекта blocks/ # - блоки (компоненты) проекта
css/ # - глобальный css-файл (будет скопирован только если существует и не пустой) css/ # - глобальные css-файлы (будут скопированы только если существует и не пустые)
fonts/ # - шрифты проекта (никак не обрабатываются, см. http://jaicab.com/localFont/) fonts/ # - шрифты проекта (будут скопированы в папку сборки, подпапку fonts/)
img/ # - глобальные картинки (будут обработаны только из корня этой папки, подпапки игнорируются) img/ # - глобальные картинки (будут обработаны только из корня этой папки, подпапки игнорируются)
js/ # - глобальный js-файл (обработается только если существует и не пустой), фреймворки (только копируются, могут быть подключены вручную) js/ # - глобальный js-файл (обработается только если существует и не пустой), фреймворки (только копируются, могут быть подключены вручную)
less/ # - диспетчер подключений и глобальные стили less/ # - диспетчер подключений и глобальные стили
......
...@@ -10,7 +10,7 @@ const dirs = pjson.config.directories; // отдельно имеем объе ...@@ -10,7 +10,7 @@ const dirs = pjson.config.directories; // отдельно имеем объе
const mkdirp = require('mkdirp'); // зависимость const mkdirp = require('mkdirp'); // зависимость
let blockName = process.argv[2]; // получим имя блока let blockName = process.argv[2]; // получим имя блока
let defaultExtensions = ['html', 'less']; // расширения по умолчанию let defaultExtensions = ['less', 'html']; // расширения по умолчанию
let extensions = uniqueArray(defaultExtensions.concat(process.argv.slice(3))); // добавим введенные при вызове расширения (если есть) let extensions = uniqueArray(defaultExtensions.concat(process.argv.slice(3))); // добавим введенные при вызове расширения (если есть)
// Если есть имя блока // Если есть имя блока
...@@ -49,7 +49,7 @@ if(blockName) { ...@@ -49,7 +49,7 @@ if(blockName) {
if(extention == 'less') { if(extention == 'less') {
LESSfileImport = '@import \'' + dirs.source + '/blocks/' + blockName + '/' + blockName + '.less\';'; LESSfileImport = '@import \'' + dirs.source + '/blocks/' + blockName + '/' + blockName + '.less\';';
fileContent = '// Для импорта в диспетчер подключений: ' + LESSfileImport + '\n\n@import \'../../less/variables.less\'; // только для удобства обращения к переменным\n\n\n.' + blockName + ' {\n \n}\n'; fileContent = '// Для импорта в диспетчер подключений: ' + LESSfileImport + '\n\n@import \'../../less/variables.less\'; // только для удобства обращения к переменным\n\n\n.' + blockName + ' {\n \n}\n';
fileCreateMsg = '[NTH] Для импорта стилей: ' + LESSfileImport; // fileCreateMsg = '[NTH] Для импорта стилей: ' + LESSfileImport;
// Создаем регулярку с импортом // Создаем регулярку с импортом
let reg = new RegExp(LESSfileImport, ''); let reg = new RegExp(LESSfileImport, '');
...@@ -92,7 +92,7 @@ if(blockName) { ...@@ -92,7 +92,7 @@ if(blockName) {
// Если это HTML // Если это HTML
else if(extention == 'html') { else if(extention == 'html') {
fileContent = '<!--DEV\n\nНужно убрать пробел между @-ами:\n\n@ @include(\'blocks/' + blockName + '/' + blockName + '.html\')\n\n-->\n<div class="' + blockName + '">content</div>\n'; fileContent = '<!--DEV\n\nНужно убрать пробел между @-ами:\n\n@ @include(\'blocks/' + blockName + '/' + blockName + '.html\')\n\n-->\n<div class="' + blockName + '">content</div>\n';
fileCreateMsg = '[NTH] Для вставки разметки: @@include(\'blocks/' + blockName + '/' + blockName + '.html\') Подробнее: https://www.npmjs.com/package/gulp-file-include'; fileCreateMsg = '[NTH] Для вставки разметки: @@include(\'blocks/' + blockName + '/' + blockName + '.html\') Подробнее: https://www.npmjs.com/package/gulp-file-include';
} }
// Если это JS // Если это JS
...@@ -100,8 +100,22 @@ if(blockName) { ...@@ -100,8 +100,22 @@ if(blockName) {
fileContent = '// (function(){\n// код\n// }());\n'; fileContent = '// (function(){\n// код\n// }());\n';
} }
// Если нужна подпапка для картинок
else if(extention == 'img') {
let imgFolder = dirPath + 'img/';
if(fileExist(imgFolder) === false) {
mkdirp(imgFolder, function (err) {
if (err) console.error(err)
else console.log('[NTH] Папка создана: ' + imgFolder)
});
}
else {
console.log('[NTH] Папка НЕ создана (уже существует) ')
}
}
// Создаем файл, если он еще не существует // Создаем файл, если он еще не существует
if(fileExist(filePath) === false) { if(fileExist(filePath) === false && extention !== 'img') {
fs.writeFile(filePath, fileContent, function(err) { fs.writeFile(filePath, fileContent, function(err) {
if(err) { if(err) {
return console.log('[NTH] Файл НЕ создан: ' + err); return console.log('[NTH] Файл НЕ создан: ' + err);
...@@ -112,7 +126,7 @@ if(blockName) { ...@@ -112,7 +126,7 @@ if(blockName) {
} }
}); });
} }
else { else if(extention !== 'img') {
console.log('[NTH] Файл НЕ создан: ' + filePath + ' (уже существует)'); console.log('[NTH] Файл НЕ создан: ' + filePath + ' (уже существует)');
} }
}); });
......
...@@ -162,6 +162,19 @@ gulp.task('img:opt', function (callback) { ...@@ -162,6 +162,19 @@ gulp.task('img:opt', function (callback) {
} }
}); });
// Копирование шрифтов
gulp.task('fonts:copy', function () {
console.log('---------- Копирование шрифтов');
return gulp.src(dirs.source + '/fonts/*.{ttf,woff,woff2,eot,svg}', {since: gulp.lastRun('fonts:copy')})
.pipe(newer(dirs.build + '/fonts')) // оставить в потоке только изменившиеся файлы
.pipe(size({
title: 'Размер',
showFiles: true,
showTotal: false,
}))
.pipe(gulp.dest(dirs.build + '/fonts'));
});
// Сборка SVG-спрайта для блока sprite-svg--localstorage // Сборка SVG-спрайта для блока sprite-svg--localstorage
gulp.task('svgstore', function (callback) { gulp.task('svgstore', function (callback) {
let spritePath = dirs.source + '/blocks/sprite-svg--localstorage/svg/'; let spritePath = dirs.source + '/blocks/sprite-svg--localstorage/svg/';
...@@ -265,7 +278,7 @@ gulp.task('clean', function () { ...@@ -265,7 +278,7 @@ gulp.task('clean', function () {
gulp.task('build', gulp.series( gulp.task('build', gulp.series(
'clean', 'clean',
'svgstore', 'svgstore',
gulp.parallel('less', 'less:docs', 'copy:css', 'img', 'js', 'js:copy'), gulp.parallel('less', 'less:docs', 'copy:css', 'img', 'js', 'js:copy', 'fonts:copy'),
'html' 'html'
)); ));
...@@ -289,6 +302,7 @@ gulp.task('serve', gulp.series('build', function() { ...@@ -289,6 +302,7 @@ gulp.task('serve', gulp.series('build', function() {
if(blocks.js) { if(blocks.js) {
gulp.watch(blocks.js, gulp.series('js', reloader)); gulp.watch(blocks.js, gulp.series('js', reloader));
} }
gulp.watch(dirs.source + '/fonts/*.{ttf,woff,woff2,eot,svg}', gulp.series('fonts:copy', reloader));
})); }));
// Отправка в GH pages (ветку gh-pages репозитория) // Отправка в GH pages (ветку gh-pages репозитория)
...@@ -310,8 +324,11 @@ function reloader(done) { ...@@ -310,8 +324,11 @@ function reloader(done) {
done(); done();
} }
// Определение собираемых компонентов // Определение собираемых компонентов
function getComponentsFiles() { function getComponentsFiles() {
// Создаем объект для служебных данных // Создаем объект для служебных данных
let сomponentsFilesList = { let сomponentsFilesList = {
less: [], // тут будут LESS-файлы в том же порядке, в котором они подключены less: [], // тут будут LESS-файлы в том же порядке, в котором они подключены
...@@ -319,83 +336,91 @@ function getComponentsFiles() { ...@@ -319,83 +336,91 @@ function getComponentsFiles() {
img: [], // тут будет массив из «путь_до_блока/img/*.{jpg,jpeg,gif,png,svg}» для всех импортируемых блоков img: [], // тут будет массив из «путь_до_блока/img/*.{jpg,jpeg,gif,png,svg}» для всех импортируемых блоков
additionalCss: [], // тут будут добавочные CSS-файлы блоков в том же порядке, в котором подключены LESS-файлы additionalCss: [], // тут будут добавочные CSS-файлы блоков в том же порядке, в котором подключены LESS-файлы
}; };
let jsLibs = []; // тут будут сторонние JS-файлы из используемых блоков (библиотеки), потом вставим в начало сomponentsFilesList.js
// Читаем файл диспетчера подключений // Читаем файл диспетчера подключений
let connectManager = fs.readFileSync(dirs.source + '/less/style.less', 'utf8'); let connectManager = fs.readFileSync(dirs.source + '/less/style.less', 'utf8');
// Делаем из строк массив, фильтруем массив, оставляя только строки с незакомментированными импортами // Делаем из строк массив, фильтруем массив, оставляя только строки с незакомментированными импортами
let fileSystem = connectManager.split('\n').filter(function(item) { let fileSystem = connectManager.split('\n').filter(function(item) {
if(/^(\s*)@import/.test(item)) return true; if(/^(\s*)@import/.test(item)) return true;
else return false; else return false;
}); });
// Обойдём массив и запишем его части в объект результирующей переменной // Обойдём массив и запишем его части в объект результирующей переменной
fileSystem.forEach(function(item, i) { fileSystem.forEach(function(item, i) {
// Попробуем вычленить блок из строки импорта // Попробуем вычленить блок из строки импорта
let componentData = /\/blocks\/(.+?)(\/)(.+?)(?=.(less|css))/g.exec(item); let componentData = /\/blocks\/(.+?)(\/)(.+?)(?=.(less|css))/g.exec(item);
// Если это блок и получилось извлечь имя файла // Если это блок и получилось извлечь имя файла
if (componentData !== null && componentData[3]) { if (componentData !== null && componentData[3]) {
// Название блока (название папки) let componentName = componentData[1]; // Название блока
let componentName = componentData[1]; let blockDir = dirs.source + '/blocks/' + componentName; // Папка блока
// Папка блока let componentFileName = componentData[3]; // Имя подключаемого файла без расширения
let blockDir = dirs.source + '/blocks/' + componentName; let jsFile = blockDir + '/' + componentFileName + '.js'; // Имя JS-файла, который нужно взять в сборку
// Имя подключаемого файла без расширения let cssFile = blockDir + '/' + componentFileName + '.css'; // Имя CSS-файла, который нужно обработать
let componentFileName = componentData[3]; let imagesDir = blockDir + '/img'; // Папка с картинками, которую нужно взять в обработку
// Имя JS-файла, который нужно взять в сборку, если он существует
let jsFile = blockDir + '/' + componentFileName + '.js';
// Имя CSS-файла, который нужно обработать, если он существует
let cssFile = blockDir + '/' + componentFileName + '.css';
// Папка с картинками, которую нужно взять в обработку, если она существует
let imagesDir = blockDir + '/img';
// Добавляем в массив с результатом LESS-файл // Добавляем в массив с результатом LESS-файл
сomponentsFilesList.less.push(dirs.source + componentData[0] + '.' + componentData[4]); сomponentsFilesList.less.push(dirs.source + componentData[0] + '.' + componentData[4]);
// Если в папке блока есть сторонние JS-файлы — добавляем их в массив с результатом (это библиотеки)
let blockFiles = fs.readdirSync(blockDir); // список файлов
let reg = new RegExp(componentName + '(\.|--)', '');
blockFiles.forEach(function(file, i) {
if(/\.js$/.test(file) && !reg.test(file)) {
if(fileExistAndHasContent(blockDir + '/' + file)) { // и если он не пуст
jsLibs.push(blockDir + '/' + file); // добавим в массив библиотек
}
}
});
jsLibs = uniqueArray(jsLibs); // уникализируем массив библиотек
// Если существует JS-файл — добавляем его в массив с результатом // Если существует JS-файл — добавляем его в массив с результатом
if(fileExistAndHasContent(jsFile)) { if(fileExistAndHasContent(jsFile)) {
сomponentsFilesList.js.push(jsFile); сomponentsFilesList.js.push(jsFile);
} }
// Если существует CSS-файл — добавляем его в массив с результатом // Если существует CSS-файл — добавляем его в массив с результатом
if(fileExistAndHasContent(cssFile)) { if(fileExistAndHasContent(cssFile)) {
сomponentsFilesList.additionalCss.push(cssFile); сomponentsFilesList.additionalCss.push(cssFile);
} }
// Если есть папка с изображениями, добавляем её в массив с результатом // Если есть папка с изображениями, добавляем её в массив с результатом
if(fileExist(imagesDir) !== false) { if(fileExist(imagesDir) !== false) {
сomponentsFilesList.img.push(imagesDir + '/*.{jpg,jpeg,gif,png,svg}'); сomponentsFilesList.img.push(imagesDir + '/*.{jpg,jpeg,gif,png,svg}');
} }
} }
}); });
// Добавим глобальныe LESS-файлы в массив с обрабатываемыми LESS-файлами // Добавим глобальныe LESS-файлы в массив с обрабатываемыми LESS-файлами
сomponentsFilesList.less.push(dirs.source + '/less/**/*.less'); сomponentsFilesList.less.push(dirs.source + '/less/**/*.less');
// Добавим глобальный JS-файл в начало массива с обрабатываемыми JS-файлами // Добавим глобальный JS-файл в начало массива с обрабатываемыми JS-файлами
if(fileExistAndHasContent(dirs.source + '/js/global-script.js')) { if(fileExistAndHasContent(dirs.source + '/js/global-script.js')) {
сomponentsFilesList.js.unshift(dirs.source + '/js/global-script.js'); сomponentsFilesList.js.unshift(dirs.source + '/js/global-script.js');
} }
// Добавим JS-библиотеки (если есть) в начало списка JS-файлов
if(jsLibs) {
сomponentsFilesList.js = jsLibs.concat(сomponentsFilesList.js);
}
// Если хочется иметь jQuery в конкатенируемом JS, раскомментируйте эти строки // Если хочется иметь jQuery в конкатенируемом JS, раскомментируйте эти строки
// if(fileExistAndHasContent(dirs.source + '/js/jquery.js')) { // if(fileExistAndHasContent(dirs.source + '/js/jquery.js')) {
// сomponentsFilesList.js.unshift(dirs.source + '/js/jquery.js'); // добавляем в самое начало // сomponentsFilesList.js.unshift(dirs.source + '/js/jquery.js'); // добавляем в начало
// } // }
// Если хочется иметь в конкатенируемом JS ещё какие-то файлы, пишите это здесь
// if(fileExistAndHasContent(dirs.source + '/js/file_name.js')) {
// сomponentsFilesList.js.unshift(dirs.source + '/js/file_name.js'); // добавляем в начало
// или
// сomponentsFilesList.js.push(dirs.source + '/js/file_name.js'); // добавляем в конец
// }
// Добавим глобальный CSS-файл в начало массива с обрабатываемыми CSS-файлами // Добавим глобальный CSS-файл в начало массива с обрабатываемыми CSS-файлами
if(fileExistAndHasContent(dirs.source + '/css/global-additional-css.css')) { if(fileExistAndHasContent(dirs.source + '/css/global-css.css')) {
сomponentsFilesList.additionalCss.unshift(dirs.source + '/css/global-additional-css.css'); сomponentsFilesList.additionalCss.unshift(dirs.source + '/css/global-css.css');
} }
// Если хочется иметь в папке сборки какие-то еще отдельные CSS-файлы, пишите их здесь
// if(fileExistAndHasContent(dirs.source + '/css/file_name.css')) {
// сomponentsFilesList.additionalCss.unshift(dirs.source + '/css/file_name.css');
// }
// Добавим глобальные изображения // Добавим глобальные изображения
сomponentsFilesList.img.unshift(dirs.source + '/img/*.{jpg,jpeg,gif,png,svg}'); сomponentsFilesList.img.unshift(dirs.source + '/img/*.{jpg,jpeg,gif,png,svg}');
сomponentsFilesList.img = uniqueArray(сomponentsFilesList.img); сomponentsFilesList.img = uniqueArray(сomponentsFilesList.img);
// Возвращаем объект со служебными данными
return сomponentsFilesList; return сomponentsFilesList;
} }
// Проверка существования файла и его размера (размер менее 2байт == файла нет) // Проверка существования файла и его размера (размер менее 2байт == файла нет)
function fileExistAndHasContent(path) { function fileExistAndHasContent(path) {
const fs = require('fs'); const fs = require('fs');
...@@ -408,6 +433,8 @@ function fileExistAndHasContent(path) { ...@@ -408,6 +433,8 @@ function fileExistAndHasContent(path) {
} }
} }
// Проверка существования файла // Проверка существования файла
function fileExist(path) { function fileExist(path) {
const fs = require('fs'); const fs = require('fs');
...@@ -418,6 +445,8 @@ function fileExist(path) { ...@@ -418,6 +445,8 @@ function fileExist(path) {
} }
} }
// Оставить в массиве только уникальные значения (убрать повторы) // Оставить в массиве только уникальные значения (убрать повторы)
function uniqueArray(arr) { function uniqueArray(arr) {
var objectTemp = {}; var objectTemp = {};
......
// ВНИМАНИЕ! В этом файле нельзя использовать блочные комментарии (/* ... */), только строчные! (//) // ВНИМАНИЕ! В этом файле нельзя использовать блочные комментарии (/* ... */), только строчные! (//)
// В этом файле нельзя писать селекторы! Есть несколько глобальных файлов стилей, остальное должно // В этом файле нельзя писать селекторы! Есть несколько глобальных файлов стилей, остальное должно
// быть по принципу БЭМ-блок = отдельный файл! // быть по принципу БЭМ-блок = отдельный файл. Смотри http://nicothin.github.io/idiomatic-pre-CSS/
@import './src/less/variables.less'; @import './src/less/variables.less';
@import './src/less/mixins/mixins.less'; @import './src/less/mixins/mixins.less';
......
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