TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
Transcript of TК°Conf. Stylelint — как и зачем линтить CSS. Андрей Ситник.
Stylelint:Как и зачем линтить CSSАндрей Ситник,Злые марсиане
1
2
Наш опенсорс
3
История человечества
10К40К250К
4
5
Неолитическая революция
6
7
История линтеров
8
Исходный код
Парсер
Анализ
Списокошибок
Линтер
9
1978 — первый линтер Lint
10
1995 — JavaScript
// true
1 == "1"
// забыт var
count = 1
11
ЛинтерыCoffeeScript или
12
CoffeeScript :-(
13
Эволюция линтеров
JSLint JSHint ESLint→ →
14
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],
…
15
ESLint: модульностьИсходный код
Парсер
Плагин 1
Список ошибок
16
Плагин 2
ESLint: автоисправление
if(foo) {
bar()}
if (foo) {
bar();
}
eslint --fix *.js
17
Популярные зависимости
1. mocha2. chai3. lodash4. grunt5. gulp6. eslint7. babel-preset-es20158. request9. async
10. shouldИсточник: https://gist.github.com/feross/e0882df2fe673d6ce064
18
ЛинтерыCSS
19
Поддержка синтаксисов
SCSS
CSSLint
SCSS Lint
CSSComb
CSS Less
20
Функции
Белыйсписок
CSSLint
SCSS Lint
CSSComb
Модульность Исправление
21
Количество правил
CSSLint
SCSS Lint
CSSComb
38
26
62
22
23
Stylelint
24
Исходный код
Парсер
Плагин 1
Список ошибок
Плагин 2
25
Модульность
26
Единый фреймворк
Полифилы
Минификация Линтинг
Примеси Изоляция
27
Сменные парсеры
CSS
SCSS Less
SugarSS Битый CSS
28
Правило — плагин PostCSS
const ruleName = "comment-no-empty"
(root, result) => {
root.walkComments(comment => {
if ( comment.text && comment.text.length === 0 ) {
report({ … })
}
}
}
29
Белый список правил
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,
…
30
Исправление
.foo {
color:black}
.foo {
color:black;
}
stylefmt *.css
31
postcss-browser-reporter
32
SCSS
CSSLint
SCSS Lint
CSSComb
CSS Less
Stylelint
33
Белыйсписок
CSSLint
SCSS Lint
CSSComb
Модульность Исправление
Stylelint
34
CSSLint
SCSS Lint
CSSComb
38
26
62
Stylelint 168
Легко писать новые правила
35
Пользователи Stylelint
36
Популярность
37
Зачем линтить
38
Cеньор
39
Юниор
Код-ревью
40
CеньорЮниор
1. Автоматическое код-ревью
Stylelint
«Я понимаю,что ты думаешь …,
но …»
41
2. Критика роботов приятнее
42
3. Обмен практиками
module.exports = {
'extend': 'stylelint-config-wordpress'
}
43
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'
44
no-descending-speci�city
#container .foo {
top: 10px;
}
…
.foo {
/* Expected selector .foo come before #container .foo */
top: 0;
}
45
no-unsupported-browser-features
.foo {
opacity: 1;
/* Features like this, which is unsupported in IE 8 */
}
46
declaration-block-no-ignored-properties
.foo {
display: inline;
width: 100px;
/* Unexpected width with display: inline */
}
47
declaration-block-no-shorthand-property-overrides
.foo {
margin-top: 10px;
margin: 0 auto;
/* Unexpected shorthand margin after margin-top */
}
48
no-indistinguishable-colors
.foo {
color: black;
}
…
.bar {
background: #010101;
/* Unexpected indistinguishable colors #010101 and black */
}
49
Как линтить
50
1. Линтер в текстовом редакторе
51
2. lint-staged — перед коммитом
"scripts": {
"lint-staged": "lint-staged",
},
"lint-staged": {
"*.css": "stylelint"
},
"pre-commit": ["lint-staged"]
52
3. Линтер в CI
53
4. Начните с популярного
module.exports = {
'extend': 'stylelint-config-standard'
}
54
55
5. Добавляйте плагины
module.exports = {
'plugins': [
'stylelint-scss'
],
'rules': {
'scss/selector-no-redundant-nesting-selector': true
}
}
56
dustinspecker/awesome-eslint
57
6. Линтер — стайл-гайд
«В стайл-гайде не должнобыть правил, которые
нельзя описать валгоритме»
58
7. Делайте исключения
.foo.is-started {
/* stylelint-disable no-unknown-animations */
/* Animation will be generated in JS*/
animation-name: js-generated-path;
}
59
stylelint-disable-reason
.foo.is-started {
/* stylelint-disable no-unknown-animations */
animation-name: js-generated-path;
/* Expected comment reason after `stylelint-disable` comment */
}
60
8. Пишите свои правила
import { utils } from "stylelint"
export const ruleName = namespace("ИМЯ")
export const messages = utils.ruleMessages(ruleName, {
expected: "ТЕКСТ ОШИБКИ",
})
export default function () {
return (root, result) => {
/* ЛОГИКА */
}
}
61
Повторы цветов — в переменные
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
}
})
})
}
62
Правила Фейсбука
slow-css-properties
filters-with-svg-files
use-variables
mobile-flexbox
63
9. Ошибка 2 раза — в правило
64
10. Линтите всё
gulp.task('default', ['lint',
'test',
'all-translated',
'spell-check',
'security-audit',
'file-size'])
65
postcss-sorting
div {
-moz-box-sizing: border-box;
width: 100%;
box-sizing: border-box;
position: absolute;
-webkit-box-sizing: border-box;
}
div {
position: absolute;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
}
66
yaspeller
$ yaspeller /home/ai/Dev/postcss/README.md
✗ /home/ai/Dev/postcss/README.md 453 ms
-----
Typos: 1
1. transorming (suggest: transforming, transporting)
-----
67
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 > [email protected] > requ… │
├───────────────┼───────────────────────────────────────────────────────┤
│ More Info │ https://nodesecurity.io/advisories/130 │
└───────────────┴───────────────────────────────────────────────────────┘
68
Ссылки
stylelint.io
@stylelint
@postcss
evl.ms/chronicles69