Введение
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-методологии. Было бы очень полезным иметь такую тему в качестве базы и наследовать свои дальнейшие проекты именно от нее.