the human linter — ilya gelman

Post on 14-Apr-2017

527 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

THE HUMAN LINTER

Ilya Gelman

Ilya Gelman

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

Sr. Developer & Consultant @ 500Tech

BAD CODE

Had to deploy fast

Didn’t read the documentation

Hoped to refactor later

It wasn’t me

New technology

'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

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

EXAMPLES FROM REAL WORLD

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

return connected;

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

return connected;!!

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

isActive = !isActive;

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

grade = grade || 100;

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

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

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

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

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

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

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

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

ES6

?{ email: email, password: password}

{ email, password }

ES6

1 == "1"TRUE

1 === "1"FALSE

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

Async Actions

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

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

ES6

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

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

ES6

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

Clean Listeners

Useless Comments

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

Unreadable Variable Names

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

Unreadable Variable Names

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

Unreadable Variable Names

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

.map(getBook);

// TODO: Implement later

// FIXME: Change later

Technical Debt

WHAT TO DO

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

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

READ THE DOCS

RE-READ THE DOCS

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,

free for open-source projects

javascripting.com

USE THIRD-PARTY

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

http://sugarjs.com

SMALL COMMITS

comm

it!

BAD

comm

it!

comm

it!

comm

it!

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!

BEST

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

comm

it!

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

js best practices

top programming mistakes

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

WE ARE HIRING

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

Ilya Gelmanilya@500tech.com

top related