SlideShare a Scribd company logo
Stylelint
Как и зачем линтить CSS
Андрей Ситник, Злые марсиане
1
2
Наш опенсорс
3
История линтеров
4
Исходный код
Парсер
Анализ
Список ошибок
Линтер
5
1978 — первый линтер Lint
6
1995 — JavaScript
// true
1 == "1"
// забыт var
count = 1
7
ЛинтерыCoffeeScript или
8
CoffeeScript :-(
9
Эволюция линтеров
JSLint JSHint ESLint→ →
10
ESLint: белый список
module.exports = {
'rules': {
'space-before-function-paren': [2],
'no-shadow-restricted-names': [2],
'computed-property-spacing': [2],
'no-empty-character-class': [2],
'no-irregular-whitespace': [2],
'no-unexpected-multiline': [2],
'no-multiple-empty-lines': [2],
'no-constant-condition': [2],
…
11
ESLint: модульность
Исходный код
Парсер
Плагин 1
Список ошибок
12
Плагин 2
ESLint: автоисправление
if(foo) {
bar()}
if (foo) {
bar();
}
eslint --fix *.js
13
Самые популярные зависимости
1. mocha
2. chai
3. lodash
4. grunt
5. gulp
6. eslint
7. babel-preset-es2015
8. request
9. async
10. should
Источник: https://gist.github.com/feross/e0882df2fe673d6ce064
14
Линтеры CSS
15
Поддержка синтаксисов
SCSS
CSSLint
SCSS Lint
CSSComb
CSS Less
16
Функции
Белый список
CSSLint
SCSS Lint
CSSComb
Модульность Исправление
17
Количество правил
CSSLint
SCSS Lint
CSSComb
38
26
62
18
19
Stylelint
20
Исходный код
Парсер
Плагин 1
Список ошибок
Плагин 2
21
На что похожа модульность?
PostCSS!
22
Единый фреймворк
Полифилы
Минификация Линтинг
Примеси Изоляция
23
Сменные парсеры
CSS
SCSS Less
SugarSS Битый CSS
24
Правило Stylelint — плагин PostCSS
const ruleName = "comment-no-empty"
(root, result) => {
root.walkComments(comment => {
if ( comment.text && comment.text.length === 0 ) {
report({ … })
}
}
}
25
Белый список правил
module.exports = {
'rules': {
'at-rule-name-case': 'lower',
'at-rule-semicolon-newline-after': 'always',
'block-closing-brace-newline-after': 'always',
'color-hex-case': 'lower',
'color-hex-length': 'short',
'color-hex-length': 'short',
'color-no-invalid-hex': true,
'indentation': 2,
…
26
Исправление
.foo {
color:black}
.foo {
color:black;
}
stylefmt *.css
27
postcss-browser-reporter
28
SCSS
CSSLint
SCSS Lint
CSSComb
CSS Less
Stylelint
29
Белый список
CSSLint
SCSS Lint
CSSComb
Модульность Исправление
Stylelint
30
CSSLint
SCSS Lint
CSSComb
38
26
62
Stylelint 150
Легко писать новые правила
31
Пользователи Stylelint
32
Популярность
33
Stylelint + CSSLint
34
Зачем линтить
35
Сеньон
36
Юниор
Код-ревью
37
СеньонЮниор
1. Меньше времени на код-ревью
Stylelint
«Я понимаю,
что ты думаешь …,
но …»
38
2. Критика роботов приятнее
39
3. Обмен практиками
module.exports = {
'extend': 'stylelint-config-wordpress'
}
40
4. Поиск ошибок
'color-no-invalid-hex',
'function-linear-gradient-no-nonstandard-direction',
'time-no-imperceptible',
'property-no-unknown',
'property-no-vendor-prefix',
'declaration-block-no-duplicate-properties',
'declaration-block-no-ignored-properties',
'declaration-block-no-shorthand-property-overrides',
'selector-class-pattern',
'selector-max-compound-selectors',
'selector-pseudo-element-no-unknown',
'selector-type-no-unknown',
'media-feature-no-missing-punctuation',
'no-unsupported-browser-features',
'no-unknown-animations',
'no-indistinguishable-colors',
'no-descending-specificity',
'no-browser-hacks'
41
no-descending-specificity
#container .foo {
top: 10px;
}
…
.foo {
/* Expected selector .foo come before #container .foo */
top: 0;
}
42
declaration-block-no-ignored-properties
.foo {
display: inline;
width: 100px;
/* Unexpected width with display: inline */
}
43
declaration-block-no-shorthand-property-overrides
.foo {
margin-top: 10px;
margin: 0 auto;
/* Unexpected shorthand margin after margin-top */
}
44
no-indistinguishable-colors
.foo {
color: black;
}
…
.bar {
background: #010101;
/* Unexpected indistinguishable colors #010101 and black */
}
45
Как линтить
46
1. Линтер в текстовом редакторе
47
2. Линтер в CI
48
3. Начните с популярного конфига
module.exports = {
'extend': 'stylelint-config-standard'
}
49
4. Добавляйте плагины
module.exports = {
'plugins': [
'stylelint-scss'
],
'rules': {
'scss/selector-no-redundant-nesting-selector': true
}
}
50
5. Линтер — стайл-гайд
«В стайл-гайде не должно
быть правил, которые нельзя
описать в алгоритме»
51
6. Делайте исключения
.foo.is-started {
/* stylelint-disable no-unknown-animations */
/* Animation will be generated in JS*/
animation-name: js-genereted-path.
}
52
stylelint-disable-reason
.foo.is-started {
/* stylelint-disable no-unknown-animations */
animation-name: js-genereted-path.
/* Expected comment reason after `stylelint-disable` com
}
53
7. Пишите свои правила
import { utils } from "stylelint"
export const ruleName = namespace("ИМЯ")
export const messages = utils.ruleMessages(ruleName, {
expected: "ТЕКСТ ОШИБКИ",
})
export default function () {
return (root, result) => {
/* ЛОГИКА */
}
}
54
Частые цвета в переменные
colors = { }
return (root, result) => {
root.walkDecls(decl => {
decl.value.match(/#[0-9a-f]{3,6}/, color => {
if ( colors[color] ) {
utils.report({ … })
} else {
colors[color] = true
}
})
})
}
55
Правила Фейсбука
​slow-css-properties
filters-with-svg-files
use-variables
mobile-flexbox
56
8. Два раза ошиблись — в правило
57
9. Линтите всё
gulp.task('default', ['lint',
'test',
'all-translated',
'spell-check',
'security-audit',
'file-size'])
58
yaspeller
$ yaspeller /home/ai/Dev/postcss/README.md
✗ /home/ai/Dev/postcss/README.md 453 ms
-----
Typos: 1
1. transorming (suggest: transforming, transporting)
-----
59
Node Security Platform
> nsp check
(+) 1 vulnerabilities found
┌───────────────┬───────────────────────────────────────────────────────┐
│ │ ReDoS via long string of semicolons │
├───────────────┼───────────────────────────────────────────────────────┤
│ Name │ tough-cookie │
├───────────────┼───────────────────────────────────────────────────────┤
│ Installed │ 2.2.2 │
├───────────────┼───────────────────────────────────────────────────────┤
│ Vulnerable │ >=0.9.7 <=2.2.2 │
├───────────────┼───────────────────────────────────────────────────────┤
│ Patched │ >=2.3.0 │
├───────────────┼───────────────────────────────────────────────────────┤
│ Path │ my-test-project@undefined > honeybadger@1.1.2 > requ… │
├───────────────┼───────────────────────────────────────────────────────┤
│ More Info │ https://nodesecurity.io/advisories/130 │
└───────────────┴───────────────────────────────────────────────────────┘
60
Ссылки
stylelint.io
@stylelint
@postcss
61

More Related Content

PDF
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
PDF
Modules and assembling of JavaScript (in russian)
PDF
Опыт разработки эффективного SPA
PDF
Многопоточность в браузере. Модель акторов — Константин Крамлих
PDF
Kranonit s16 (python). dmitry furzenko
PDF
Алексей Андросов - Debugger: Отладка кода
PDF
Инструментируй это
PDF
Филипп Ковалев — Путь в npm
TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
Modules and assembling of JavaScript (in russian)
Опыт разработки эффективного SPA
Многопоточность в браузере. Модель акторов — Константин Крамлих
Kranonit s16 (python). dmitry furzenko
Алексей Андросов - Debugger: Отладка кода
Инструментируй это
Филипп Ковалев — Путь в npm

More from WebCamp (20)

PDF
WebCamp 2016: Python.Максим Климишин.Типизированный Python
PDF
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
PDF
WebCamp 2016.PHP.Боднарчук Михаил.BDD на практике с Codeception
PDF
WebCamp2016:Front-End.Катерина Поршнева.Эволюция CSS: от темных времен до CSS...
PDF
WebCamp 2016: Python.Павел Коломиец.Использование микросервисов при написании...
PDF
WebCamp 2016: Python_Кирилл Перевозчиков _Рецепты приготовления uWSGI
PDF
WebCamp 2016: PHP. Дмитрий Науменко: Рецепты для Yii2.
PDF
WebCamp 2016: PHP.Сергей Яковлев.Phalcon 3
PDF
WebCamp 2016: PHP.Денис Потапов.Рефакторим код не задумываясь
PDF
WebCamp 2016: PHP.Алексей Петров.PHP at Scale: System Architect Toolbox
ODP
WebCamp2016:Front-End_Андрей Копёнкин_Оптимизируем мобильный веб полностью
PDF
WebCamp2016:Front-End_Юрий Артюх_Современные подходы в верстке
PDF
WebCamp2016:Front-End_Роман Якобчук_Relay, GraphQL и остальные радости соврем...
PDF
WebCamp2016:BizDev_Алексей Иваница_Как построить и монетизировать мобильный п...
PDF
WebCamp 2016: BizDev. Андрей Моспан: Правда ли, что продукт стоит ровно столь...
PDF
WebCamp 2016: BizDev. Марина Никитчук : Искусство продажи мечты, а не сервиса.
PDF
WebCamp 2016: BizDev. Александр Борняков: Маркетинг в США: как привлечь к себ...
PDF
WebCamp 2016: BizDev. Кейт Голдберг: Agile business development: как применят...
PDF
WebCamp 2016: DevOps. Ярослав Погребняк: Gobetween - новый лоад балансер для ...
PDF
WebCamp 2016: DevOps. Николай Дойков: Опыт создания клауда для потокового вид...
WebCamp 2016: Python.Максим Климишин.Типизированный Python
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp 2016.PHP.Боднарчук Михаил.BDD на практике с Codeception
WebCamp2016:Front-End.Катерина Поршнева.Эволюция CSS: от темных времен до CSS...
WebCamp 2016: Python.Павел Коломиец.Использование микросервисов при написании...
WebCamp 2016: Python_Кирилл Перевозчиков _Рецепты приготовления uWSGI
WebCamp 2016: PHP. Дмитрий Науменко: Рецепты для Yii2.
WebCamp 2016: PHP.Сергей Яковлев.Phalcon 3
WebCamp 2016: PHP.Денис Потапов.Рефакторим код не задумываясь
WebCamp 2016: PHP.Алексей Петров.PHP at Scale: System Architect Toolbox
WebCamp2016:Front-End_Андрей Копёнкин_Оптимизируем мобильный веб полностью
WebCamp2016:Front-End_Юрий Артюх_Современные подходы в верстке
WebCamp2016:Front-End_Роман Якобчук_Relay, GraphQL и остальные радости соврем...
WebCamp2016:BizDev_Алексей Иваница_Как построить и монетизировать мобильный п...
WebCamp 2016: BizDev. Андрей Моспан: Правда ли, что продукт стоит ровно столь...
WebCamp 2016: BizDev. Марина Никитчук : Искусство продажи мечты, а не сервиса.
WebCamp 2016: BizDev. Александр Борняков: Маркетинг в США: как привлечь к себ...
WebCamp 2016: BizDev. Кейт Голдберг: Agile business development: как применят...
WebCamp 2016: DevOps. Ярослав Погребняк: Gobetween - новый лоад балансер для ...
WebCamp 2016: DevOps. Николай Дойков: Опыт создания клауда для потокового вид...
Ad

WebCamp 2016: Front-end. Андрей Ситник: Stylelint — как и зачем линтить CSS