Введение
Frontend-составляющая любого ecommerce-проекта (и не только) предполагает множественное использование базовых компонентов (кнопки, элементы форм) в самых различных контекстах. Визуальное представление разбитых на самостоятельные части комплексных компонентов позволяет разработчику лучше структурировать его HTML/CSS код. На данный момент существуют инструменты, которые позволяют генерировать оформленный styleguide вашего проекта на основе комментариев в исходном коде LESS/SCSS-файлов. Одним из таких инструментов является sc5-styleguide (Источник 1), и в данной статье мы рассмотрим основные шаги, которые позволят внедрить его в типовой проект на Magento 2.
Краткий обзор
SC5-styleguide базируется в своем синтаксисе на KSS (Knyle Style Sheets) (Источник 2). В источнике №1 есть вся необходимая информация по настройке SC5 в таких системах сборки как GRUNT/GULP . Давайте рассмотрим небольшой пример исходного кода оформленного в SC5 веб-компонента в контексте Magento 2:
// Primary button
//
// default - the interactive default state
// :focus - the state when the field has focus
// :hover - the state when the field has focus
// disabled - disabled state
//
// markup:
// <button class="example-button-4 {$modifiers}" type="button"><span>Button</span></button>
//
// Styleguide 1.2.8
.example-button-4 {
.lib-button-primary(
@_button-margin: 3px
);
}
Для любого разработчика, работавшего с темой blank в Magento 2, окраска данных кнопок окажется знакомой. Данный скриншот показывает то, с какой легкостью и минимальным количеством строк кода можно задокументировать разрабатываемую тему. Причем ничто не будет мешать наследоваться от такой темы, вносить малейшие корректировки в код, и получать иной окрас кнопок в дочерней теме изменяя только less-переменные.
Давайте проанализируем представленный выше код: первая строка это ни что иное как название желаемой секции в стайлгайде, далее с 3 по 5 строки у нас описан набор псевдоселекторов, каждый из которых дублирует изначальный вид компонента и вставляет его в preview-секцию с измененным {$modifiers}. Таким образом мы получаем состояния кнопок при фокусе, неактивном состоянии и наведенном на них курсором мыши. С 7 строки начинается html-структура компонента и заканчивается первой встречающейся пустой закомментированной строкой. Последняя закомментированная строка означает конец текущей секции, в не так же задан ее числовой идентификатор. В самом конце у нас имеется css-правило, которое стилизует кнопки миксином из Magento 2 UI Library. Живую демо-версию SC5-styleguide вы можете посмотреть в источнике 3
Magento 2 с точки зрения frontend-части не лишена недостатков. Одним из таких показателей является относительно недавний отказ компании Magento от поддержки Internet Explorer 9 , автор статьи не располагает точными сведениями по такому решению но владеет некоторыми догадками. В скомпилированных css файлах базовой темы blank количество селекторов превышает отметку в 4096, таким образом некоторая область стилей не будет видима для Internet Explorer 9 вовсе. Учтите что это базовая тема, это значит что результаты скомпилированных стилей для дочерних от нее тем будут весьма ошеломительными. Такое обильное количество css-кода для базовой темы можно объяснить разными причинами, например отсутствие следования какой-либо методологии написания CSS-кода, его дублирование и как следствие большой уровень нэстинга. SC5-styleguide не является панацеей, но все же способен направить разработчика на грамотное и структурированное написание css-кода.
Интеграция SC5-styleguide в GULP-конфигурацию snowdog/frontools
На данный момент frontools (Источник 4) является лучшей альтернативой выходящей из коробки magento 2 конфигурации GRUNT. В frontools есть команда dev (таск лист так же в источнике 4), которая запускает watcher less-файлов, запускает browsersync и проксирует ваш веб-сайт по желаемому url. Это та задача, код которой мы будем модифицировать для запуска SC5-styleguide. Кстати при клонировании проекта frontools не забудьте переключиться на версию 0.11.4 , это тот последний релиз который поддерживает темы luma и blank, в последних релизах сборка ориентирована на scss-аналог темы blank (Источник 5). Давайте посмотрим на листинг файла task/dev.js:
'use strict';
module.exports = function() { // eslint-disable-line func-names
// Open browser-sync session and start watchers
this.opts.plugins.runSequence('browser-sync', 'watch');
};
Здесь описана логика последовательного выполнения задач ‘browser-sync’ , ‘watch’, давайте добавим сюда задачу styleguide, получаем следующий вид:
'use strict';
module.exports = function() { // eslint-disable-line func-names
// Open browser-sync session and start watchers
this.opts.plugins.runSequence('browser-sync', 'watch', ‘styleguide’);
};
Логика задачи styleguide будет описана в task/styleguide.js, ниже приведен листинг:
'use strict';
module.exports = function() {
const that = this,
gulp = this.gulp,
styleguide = this.opts.plugins.sc5Styleguide,
config = this.opts.configs,
plugins = this.opts.plugins,
theme = plugins.util.env.theme,
dest = config.themes[theme].dest,
locale = config.themes[theme].locale,
src = config.themes[theme].src,
files = plugins.globby.sync(['../' + dest + '/' + locale + '/css/**/' + '*.less']),
libFonts = '../lib/web/fonts/**/*',
images = '../' + src + '/web/images/styleguide/*';
gulp.src(libFonts).pipe(gulp.dest('../' + dest + '/' + locale + '/output/fonts'));
gulp.src(images).pipe(gulp.dest('../' + dest + '/' + locale + '/output/assets/img'));
that.opts.plugins.runSequence('styleguide_applystyles', 'styleguide_generate');
gulp.watch(files, function() {
that.opts.plugins.runSequence('styleguide_applystyles', 'styleguide_generate')
})
};
Рассмотрим основные строки:
- В 5 строке ссылаемся на gulp-плагин sc5-styleguide
- 12 строка - корневые .less файлы нашей темы (styles-m.less и styles-l.less)
- 13 строка - ссылаемся на шрифты Magento для дальнейшего копирования в директорию выходного контента SC5
- 14 строка - ассеты для стайлгайда (в данном случае просто картинки)
- 15 строка - копируем шрифты в каталог output нашего стайлгайда
- 16 строка - копируем туда же картинки
- 17 строка - выполняем последовательно задачи компиляции less-файлов темы и генерации стайлгайда (листинг задач будет приведен ниже)
- 18 строка - запускам watcher над files, при их изменении снова последовательно запускаем ‘styleguide_applystyles’ и ‘styleguide_generate’
Рассмотрим листинг задач ‘styleguide_applystyles’ и ‘styleguide_generate’, логика которых будет находиться в styleguide_applystyles.js и styleguide_generate.js соответственно
'use strict';
module.exports = function() {
const gulp = this.gulp,
styleguide = this.opts.plugins.sc5Styleguide,
less = require('gulp-less'),
outputPath = 'output',
util = this.opts.plugins.util,
config = this.opts.configs,
plugins = this.opts.plugins,
theme = plugins.util.env.theme,
locale = config.themes[theme].locale,
dest = config.themes[theme].dest,
files = plugins.globby.sync([
'../' + dest + '/' + locale + '/css/*.less',
'!../' + dest + '/' + locale + '/css/_*.less'
]);
return gulp.src(files)
.pipe(less({ errLogToConsole: true }))
.pipe(styleguide.applyStyles())
.pipe(gulp.dest('../' + dest + '/' + locale + '/output'));
}
- 13 строка - ссылаемся на корневые less файлы
- 17 строка - компилируем less и складываем их в output нашего стайлгайда, наличие специального каталога для статичного контента в Magento 2 намекает на тот путь куда мы бы хотели складывать сгенерированный стайлгайд (pub/static/frontend/{vendor}/{theme_name}/{locale}/{output})
Далее рассмотрим styleguide_generate.js
'use strict';
module.exports = function() {
const gulp = this.gulp,
styleguide = this.opts.plugins.sc5Styleguide,
less = require('gulp-less'),
outputPath = 'output',
util = this.opts.plugins.util,
config = this.opts.configs,
plugins = this.opts.plugins,
theme = plugins.util.env.theme,
locale = config.themes[theme].locale,
dest = config.themes[theme].dest,
src = config.themes[theme].src,
readme = plugins.globby.sync('../' + src + '/readme.md'),
files = plugins.globby.sync([
'../' + dest + '/' + locale + '/css/styleguide/**/*.less',
'../' + dest + '/' + locale + '/css/source/_theme_extend.less',
'../' + dest + '/' + locale + '/css/source/_theme.less'
])
return gulp.src(files)
.pipe(styleguide.generate({
title: 'Styleguide',
server: true,
port: 3010,
rootPath: '../' + dest + '/' + locale + '/output',
overviewPath: readme
}))
.pipe(gulp.dest('../' + dest + '/' + locale + '/output'));
}
- Обратите внимание на переменную files в этом файле, здесь содержится массив с путями к файлам из каталога pub/static. Для генерации стайлгайда мы жестко фиксируем набор файлов, в которых будет задокументированный код в KSS-нотации (все less-файлы из каталога css/styleguide и два файла, которые должны содержать список переопределенных less-переменных темы blank или luma, это theme.less и theme_extend.less). theme.less должен содержать скопированный код из родительской темы, поэтому лучше подключить расширяющий его theme_extend.less и переопределять переменные именно в нем
- 20 строка запускает задачу generate плагина sc5-styleguide со следующими параметрами: title - появляется на главной странице стайлгайда, server - выставляем true для включения встроенного веб-сервера sc5, который будет отдавать нам контент по адресу localhost:3010 , порт мы соответственно указали в параметре port , rootPath - содержит путь к каталогу куда складываем сгенерированный стайлгайд, overviewPath - опциональный параметр, ссылается на файл readme.md в котором содержится описательный контент главной страницы стайлгайда
- 28 строка - складываем контент стайлгайда в pub/static/frontend/{vendor}/{theme_name}/{locale}/output
Таким образом после вызова команды dev --theme my_theme мы запускаем локальный веб-сервер, который отдает нам стайлгайд. Ниже показан скриншот результата нашей работы:
Заключение
Таким образом мы внедрили “живой” стайлгайд в типовой проект на Magento 2. При желании можно задокументировать весь Magento 2 UI Library и смотреть как преображаются базовые или комплексные компоненты веб-страниц в разных темах. По сути это будет означать полное копирование всей библиотеки (lib/web/css/source) в свою тему, это ни что иное как оверрайд всей базовой стилизации Magento 2. Учтите что при апгрейде Magento на новые версии эти файлы теоретически могут изменяться, а вследствие перезаписи этих файлов вы теряете актуальные фиксы со стороны Magento. Этот инструмент также может побудить и на более амбициозные цели, к примеру попытка рефакторинга базовых компонентов Magento на уровне различных модулей (Catalog, Customer, Wishlist и тд), применяя при этом лучшие практики по написанию CSS-кода и новейшие CSS-методологии. Было бы очень полезным иметь такую тему в качестве базы и наследовать свои дальнейшие проекты именно от нее.
