Robots Must Suffer
linters and tools for front-end development
Andrey Sitnik
© Eric Joyner
Evil Martians
I am from Russia
Lead front-end developer at
Author of
Autoprefixer
PostCSS
Why did I create PostCSS
?
Two types of tasks
Creative tasks
Boring tasks
Humans vs. robots
Creative tasks
Boring tasks
Humans
Robots
Robots don’t make mistakes
Work process
Talk
Analyze
Code
Test
Robots!
Talk
Analyze
Code
Test
Robots must suffer
© Eric Joyner
© Eric Joyner
Part 2: What is linters?
Talk
Analyze
Code
Test
Test
- Lint
- Unit tests
- Integration tests
- Benchmarks
Talk
Analyze
Code
Test
This talk is about linters
- Lint
- Unit tests
- Integration tests
- Benchmarks
What are linters?
Linters find mistakes in source code
Source code
Parser
Analysis
Errors list
Linting process
Unit tests vs. linters
y = 2 − (−x)
Unit tests
in: 2 out: 0
y(2) = 4, !== 0
Linters
−(−n) → +n
Unit tests vs. linters
Unit tests
Linters
Check input and output
Don’t find an error
Check source code
Tell exact line
Unit tests + linters =
"scripts": {
"test": "npm run lint && npm run unit-test"
Part 3
Popular
linters
© Eric Joyner
Node.js app
app.all('/apps/:user_id', request => {
initial = extract(request.body)
})
After 4 hours of debugging
app.all('/apps/:user_id', request => {
initial = extract(request.body)
})
app.all('/apps/:user_id', request => {
var initial = extract(request.body)
})
var
Real story. Tests didn’t help.
ESLint could fix it
app.all('/apps/:user_id', request => {
initial = extract(request.body)
})
ESLint: initial is not defined app.js:2:3
The most popular dependencies
- mocha
- chai
-
eslint
- babel-preset-es2015
- lodash
JS linters evolution
JSLint
JSHint
ESLint
→
→
CSS
.foo {
margin-top: 20px;
width: 100px;
height: 100px;
}
Horizontal centering
.foo {
margin-top: 20px;
width: 100px;
height: 100px;
margin: 0 auto;
}
After 5 min of debugging
.foo {
margin-top: 20px;
width: 100px;
height: 100px;
margin: 0 auto;
}
Stylelint could fix it
.foo {
margin-top: 20px;
width: 100px;
height: 100px;
margin: 0 auto;
}
Stylelint: this overrides the longhand property before it app.css:5:3
Stylelint languages
*.pcss
*.scss
*.vue
postcss-scss
postcss-html
*.less
postcss-less
Stylelint users
Part 4 Why
© Eric Joyner
Writing code vs. debug time
Dev
Debug
10 min
30 min
Normal
#1 Linters reduce debug time
Dev
Debug
10 min
30 min
Normal
10 min
25 min
With linters
Code reviews
Senior
Junior
#2 Linters reduce code reviews
Senior
Junior
Linter
It is hard to be a junior
Junior
Senior
Fixes
#3 Linters make juniors happy
Junior
Linter
Fixes
Big companies → multiple teams
Team 1
Team 2
Idea
?
#4 Sharing ideas
Team 1
Team 2
Linter config
Idea
Part 5 How
© Eric Joyner
Step 1 Install linters via npm
npm install --save-dev eslint stylelint
Step 2 Create a config
.eslintrc
.stylelintrc
{
"rules": {
"no-console": "error"
}
}
Too many rules
ESLint: 300 rules
Stylelint: 161 rules
Step 3 Extend shareable config
{
"extends": "standard",
"rules": {
"no-console": "error"
}
}
npm install --save-dev eslint-config-standard
Popular configs
ESLint
Stylelint
Step 4 Linter plugins for text editors
Linter plugins text editor
Sublime Text
VS Code
Too many errors?
ESLint: 250 errors in 100 files
Step 5 Fix automatically
eslint --fix src/**/*.js stylelint --fix src/**/*.css
Other developers ignore linter
Good developer
Bad developer
git commit …
npm run test
npm run lint
git push …
git commit …
git push …
Step 6 lint-staged
git commit …
run pre-commit hook
git add a.css
run stylelint a.css
Stylelint: 1 error
git: commit canceled
Install lint-staged
npm install --save-dev lint-staged pre-commit
lint-staged config
"scripts": {
"lint-staged": "lint-staged",
},
"lint-staged": {
"*.css": "stylelint"
},
"pre-commit": ["lint-staged"]
Step 6 Write custom plugins
Stylelint rule = simple PostCSS plugin
Facebook custom rules
-
slow-css-properties
-
filters-with-svg-files
-
use-variables
-
mobile-flexbox
Happened twice → write custom rule
Senior
Junior
Linter
Custom rule
Part 6
Other linters
© Eric Joyner
The best ESLint plugins
My favorite ESLint plugins
-
eslint-config-import
-
eslint-plugin-security
-
eslint-plugin-node
The best Stylelint plugins
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%;
}
Sort CSS properties
Lint English
$ yaspeller /home/ai/Dev/postcss/README.md
✗ /home/ai/Dev/postcss/README.md 453 ms
-----
Typos: 1
1. transorming (suggest: transforming, transporting)
-----
Check security in Node.js dependencies
> 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 │
└───────────────┴───────────────────────────────────────────────────────┘
Check webpack bundle size
Check accessibility
pa11y --config ./path/to/config.json http://example.com
The end
© Eric Joyner
Links
@andreysitnik VPN☺
@evilmartians VPN☺