the human linter

49
THE HUMAN LINTER Ilya Gelman

Upload: ilya-gelman

Post on 15-Jan-2017

211 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: The Human Linter

THE HUMAN LINTER

Ilya Gelman

Page 2: The Human Linter

Ilya Gelman

- Organizer of AngularJS-IL - Organizer of ReactJS-Israel - Passionate about design and UX

Sr. Developer & Consultant @ 500Tech

Page 3: The Human Linter

BAD CODE

Page 4: The Human Linter

Had to deploy fast

Didn’t read the documentation

Hoped to refactor later

It wasn’t me

New technology

Page 5: The Human Linter

'use strict'; const React = require('react'); const BaseMixin = require('mixins/base'); const ChildrenMixin = require('mixins/children'); const ComponentUtils = require('utils/component'); const Config = require('lib/config'); const Notification = require('components/notifications'); modure.exports = React.createClass({ displayName:'Form', mixins:[BaseMixin,ChildrenMixin], propTypes: {metadata: React.PropTypes.object.isRequired, notifications: React.PropTypes.array }, getChildContext(){ return { action: this._handleAction, formId: this.props.id}},

⌥ ⌘ L

Page 6: The Human Linter

'use strict'; const React = require('react'); const BaseMixin = require('mixins/base'); const ChildrenMixin = require('mixins/children'); const ComponentUtils = require('utils/component'); const Config = require('lib/config'); const Notification = require('components/notifications'); modure.exports = React.createClass({ displayName: 'Form', mixins: [BaseMixin, ChildrenMixin], propTypes: { metadata: React.PropTypes.object.isRequired, notifications: React.PropTypes.array }, getChildContext() { return { action: this._handleAction, formId: this.props.id } }

Page 7: The Human Linter

EXAMPLES FROM REAL WORLD

Page 8: The Human Linter

?if (connected) { return true; } else { return false; }

return connected;

Page 9: The Human Linter

?if (connected) { return true; } else { return false; }

return connected;!!

Page 10: The Human Linter

?if (!isActive) { isActive = true; } else { isActive = false; }

isActive = !isActive;

Page 11: The Human Linter

?if (!grade) { grade = 100; }

grade = grade || 100;

Page 12: The Human Linter

?if (books) { books.map(fn); } else { return []; }

(books || []).map(fn);

Page 13: The Human Linter

?let point = {}; point.x = 10; point.y = 29;

const point = { x: 10, y: 29 };

Page 14: The Human Linter

?while (processing) { const config = { option1: 123, option2: 456 }; // ...}

const config = { option1: 123, option2: 456}; while (processing) { // ...}

Page 15: The Human Linter

?.sort((a, b) => { return a > b; });

.sort((a, b) => a > b);

ES6

Page 16: The Human Linter

?{ email: email, password: password}

{ email, password }

ES6

Page 17: The Human Linter
Page 18: The Human Linter

1 == "1"TRUE

Page 19: The Human Linter

1 === "1"FALSE

Page 20: The Human Linter

http://codepen.io/borisd/pen/jbNory

Async Actions

$http.get(API_URL).then(function () { redirectTo(profileUrl)});

Page 21: The Human Linter

function perimeter(top, right, bottom, left) { return Math.sum(top, right, bottom, left); } perimeter(20, 15, 23, 12);

ES6

Page 22: The Human Linter

function perimeter(options = {}) { const opt = options; return Math.sum(opt.top, opt.right, opt.bottom, opt.left); } perimeter({ top: 20, bottom: 23, left: 12, right: 15 });

ES6

* Not the best code, only shows options hash example

Page 23: The Human Linter

function perimeter(top, right, bottom, left) { return Math.sum(top, right, bottom, left); } perimeter(/* top */ 20, /* right */ 15, /* bottom */ 23, /* left */ 12);

ES6

Page 24: The Human Linter

element.addEventListener('click', listener, false); element.removeEventListener('click', listener, false);

Clean Listeners

Page 25: The Human Linter

Useless Comments

// Clicks the edit icon T.simulate.click(editBtn);

Page 26: The Human Linter

Unreadable Variable Names

.map((b, i) => { return { catalogId: i, description: getDescription(b.isbn), }; });

Page 27: The Human Linter

Unreadable Variable Names

.map((book, index) => { return { catalogId: index, description: getDescription(book.isbn), }; });

Page 28: The Human Linter

Unreadable Variable Names

const getBook = (book, index) => { return { catalogId: index, description: getDescription(book.isbn), }; }

.map(getBook);

Page 29: The Human Linter

// TODO: Implement later

// FIXME: Change later

Technical Debt

Page 30: The Human Linter

WHAT TO DO

Page 31: The Human Linter

if (viewLoading) { element.classList.add('active'); } else { element.classList.remove('active'); }

element.classList.toggle('active', viewLoading);

Page 32: The Human Linter

READ THE DOCS

Page 33: The Human Linter

RE-READ THE DOCS

Page 34: The Human Linter

ESLint

https://github.com/500tech/code-style

.eslintrc

"generators": true, "modules": true, "objectLiteralComputedProperties": true, "objectLiteralDuplicateProperties": false, "objectLiteralShorthandMethods": true, "objectLiteralShorthandProperties": true, "restParams": true, "spread": true, "superInFunctions": true, "templateStrings": true, "jsx": true, "regexYFlag": true, "regexUFlag": true, }, "rules": { // Disabled rules "complexity": 0, "no-extend-native": 0, "no-process-env": 0, "init-declarations": 0, "no-restricted-modules": 0, "no-sync": 0, "no-undef-init": 0, "linebreak-style": 0, "no-inline-comments": 0, "no-new-object": 0, "no-ternary": 0, "padded-blocks": 0, "no-inner-declarations": 0, "id-length": 0, "id-match": 0, "no-underscore-dangle": 0, "sort-vars": 0, "max-statements": 0, // Warning level "comma-dangle": [1, "always-multiline"], "no-console": 1, "no-control-regex": 1, "no-empty": 1, "no-func-assign": 1, "consistent-return": 1, "curly": [1, "all"], "default-case": 1, "dot-notation": 1, "no-alert": 1, "no-multi-spaces": 1, "no-param-reassign": 1, "no-warning-comments": [1, { "terms": ["todo", "radix": 1, "no-path-concat": 1, "no-process-exit": 1, "lines-around-comment": [1, { "beforeBlockComment": "constructor-super": 1, "prefer-template": 1,

Page 35: The Human Linter
Page 36: The Human Linter

free for open-source projects

Page 37: The Human Linter

javascripting.com

USE THIRD-PARTY

Page 38: The Human Linter

orders.map('customer').unique().average('payment');

http://sugarjs.com

Page 39: The Human Linter

SMALL COMMITS

Page 40: The Human Linter

comm

it!

BAD

comm

it!

comm

it!

comm

it!

Page 41: The Human Linter

GOOD

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

Page 42: The Human Linter

BEST

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

Page 43: The Human Linter

Also, review "on-the-fly" to save time

Page 45: The Human Linter

js best practices

Page 46: The Human Linter

top programming mistakes

Page 47: The Human Linter

http://amzn.to/1bSAYsh http://amzn.to/1ydGaoB http://amzn.to/1K93J6h

Page 48: The Human Linter

WE ARE HIRING

Page 49: The Human Linter

Read our blog:http://blog.500tech.com

Ilya [email protected]