Введение

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')
   })
};

Рассмотрим основные строки:

  1. В 5 строке ссылаемся на gulp-плагин sc5-styleguide
  2. 12 строка - корневые .less файлы нашей темы (styles-m.less и styles-l.less)
  3. 13 строка - ссылаемся на шрифты Magento для дальнейшего копирования в директорию выходного контента SC5
  4. 14 строка - ассеты для стайлгайда (в данном случае просто картинки)
  5. 15 строка - копируем шрифты в каталог output нашего стайлгайда
  6. 16 строка - копируем туда же картинки
  7. 17 строка - выполняем последовательно задачи компиляции less-файлов темы и генерации стайлгайда (листинг задач будет приведен ниже)
  8. 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'));
}
  1. 13 строка - ссылаемся на корневые less файлы
  2. 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'));
}
  1. Обратите внимание на переменную files в этом файле, здесь содержится массив с путями к файлам из каталога pub/static. Для генерации стайлгайда мы жестко фиксируем набор файлов, в которых будет задокументированный код в KSS-нотации (все less-файлы из каталога css/styleguide и два файла, которые должны содержать список переопределенных less-переменных темы blank или luma, это theme.less и theme_extend.less). theme.less должен содержать скопированный код из родительской темы, поэтому лучше подключить расширяющий его theme_extend.less и переопределять переменные именно в нем
  2. 20 строка запускает задачу generate плагина sc5-styleguide со следующими параметрами: title - появляется на главной странице стайлгайда, server - выставляем true для включения встроенного веб-сервера sc5, который будет отдавать нам контент по адресу localhost:3010 , порт мы соответственно указали в параметре port , rootPath - содержит путь к каталогу куда складываем сгенерированный стайлгайд, overviewPath - опциональный параметр, ссылается на файл readme.md в котором содержится описательный контент главной страницы стайлгайда
  3. 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-методологии. Было бы очень полезным иметь такую тему в качестве базы и наследовать свои дальнейшие проекты именно от нее.

Источники

  1. Проект SC5-styleguide на Github
  2. Синтаксис KSS
  3. Демо SC5-styleguide
  4. Проект Frontools на Github
  5. Тема blank на базе SCSS для Magento 2