Download - HTML5 Developer Conference 2013: Javascript Insights

Transcript
Page 1: HTML5 Developer Conference 2013: Javascript Insights

JavaScript InsightsTools for Improving JS Code Quality

Ariya Hidayat

@ariyahidayatHTML5 Developer Conference

San Francisco, October 22, 2013

Ann Robson@arobson

Page 2: HTML5 Developer Conference 2013: Javascript Insights

car salesmanAriya

Ann

Page 3: HTML5 Developer Conference 2013: Javascript Insights

Why JavaScript code quality tools?

Page 4: HTML5 Developer Conference 2013: Javascript Insights

It’s how we work together.

Page 5: HTML5 Developer Conference 2013: Javascript Insights

And it’s how we level up.

Page 6: HTML5 Developer Conference 2013: Javascript Insights

varied...

JavaScript Toolssome to be developed…. ALL are open source

?$0

$0

$0

$0?

Page 7: HTML5 Developer Conference 2013: Javascript Insights

Power(ful) tools

Page 8: HTML5 Developer Conference 2013: Javascript Insights

Linter

Code Coverage

Cyclomatic Complexity

Page 9: HTML5 Developer Conference 2013: Javascript Insights

Linter

JSHint http://jshint.com

Enforces style guide

Team standards: .jshintrc

Page 10: HTML5 Developer Conference 2013: Javascript Insights

Code Coverage

Istanbulhttp://ariya.ofilabs.com/2012/12/javascript-code-coverage-with-istanbul.html

http://gotwarlost.github.io/istanbul/

Page 11: HTML5 Developer Conference 2013: Javascript Insights

If you think JSLint hurts your feelings,wait until you use Istanbul

@davglass from Yahoo!

Page 12: HTML5 Developer Conference 2013: Javascript Insights

Code Complexity

if (true) "foo"; else "bar";

Control Flow Graph

6 edges

6 nodes

1 exit

Cyclomatic Complexity = 2

JSComplexity http://jscomplexity.org

Page 13: HTML5 Developer Conference 2013: Javascript Insights

Complexity Visualization

https://github.com/jsoverson/platoPlatoContinuous Delivery for JavaScript Applications

Jarrod OversonRoom E-131 Wed 11.40am

Page 14: HTML5 Developer Conference 2013: Javascript Insights

Pre-commit HooksMay include all tools previously mentioned: - linting - code coverage - code complexityAlso, - validation: esvalidate

- custom

Page 15: HTML5 Developer Conference 2013: Javascript Insights

Demos

Page 16: HTML5 Developer Conference 2013: Javascript Insights

Hard Thresholds on Code Coverage

http://ariya.ofilabs.com/2013/05/hard-thresholds-on-javascript-code-coverage.html

istanbul check-coverage --statement -5 --branch -3 --function 100

Page 17: HTML5 Developer Conference 2013: Javascript Insights

Pre-commit Hooks Escape!git commit -n

Page 18: HTML5 Developer Conference 2013: Javascript Insights

Composable Tools

Page 19: HTML5 Developer Conference 2013: Javascript Insights

Stray logging Strict mode violations

Unused variables Nested ternary conditionals

Polluting variables Boolean traps

Page 20: HTML5 Developer Conference 2013: Javascript Insights

{ type: "Program", body: [ { type: "VariableDeclaration", declarations: [ { type: "VariableDeclarator", id: { type: "Identifier", name: "answer" }, init: { type: "Literal", value: 42, raw: "42" } } ], kind: "var" } ]}

Code → Syntax Tree

var answer = 42;

Esprimahttp://esprima.org

Page 21: HTML5 Developer Conference 2013: Javascript Insights

console.log? debugger?

function detect_console(code) {  function check(node) { if (node.type === 'CallExpression') { if (node.callee.type === 'MemberExpression') { if (node.callee.object.name === 'console') { alert('console call at line', node.loc.start.line); } } } }  var tree = esprima.parse(code, { loc: true }); estraverse.traverse(tree, { enter:check });}

Page 22: HTML5 Developer Conference 2013: Javascript Insights

Strict Mode Validator

'use strict';block = { color: 'blue', height: 20, width: 10, color: 'red'};

Duplicate data property in objectliteral not allowed in strict mode

http://ariya.ofilabs.com/2012/10/validating-strict-mode.html

Page 23: HTML5 Developer Conference 2013: Javascript Insights

Polluting Variables

var height;// some fancy processingheigth = 200;

Leaks to global

test.js:3heigth = 200;^LeakError: global leak detected: heigth

https://github.com/kesla/node-leaky

http://ariya.ofilabs.com/2012/11/polluting-and-unused-javascript-variables.html

Page 24: HTML5 Developer Conference 2013: Javascript Insights

Unused Variables

http://ariya.ofilabs.com/2012/11/polluting-and-unused-javascript-variables.html

test.js height - on line 1

https://github.com/Kami/node-unused

var height;// some fancy processingheigth = 200;

Declared but not used

Page 25: HTML5 Developer Conference 2013: Javascript Insights

Nested Ternary Conditionals

var str = (age < 1) ? "baby" : (age < 5) ? "toddler" : (age < 18) ? "child": "adult";

http://ariya.ofilabs.com/2012/10/detecting-nested-ternary-conditionals.html

Page 26: HTML5 Developer Conference 2013: Javascript Insights

“Boolean Trap” Finder

Can you make up your mind? treeItem.setState(true,

false);

Obfuscated choice var volumeSlider = new Slider(false);

Double-negative component.setHidden(false);filter.setCaseInsensitive(false);

http://ariya.ofilabs.com/2012/06/detecting-boolean-traps-with-esprima.html

The more the merrier event.initKeyEvent("keypress", true, true,null, null, false, false, false, false, 9, 0);

Page 27: HTML5 Developer Conference 2013: Javascript Insights

Future linting

ESLint

How we might collect the tools we make

https://github.com/nzakas/eslint

Page 28: HTML5 Developer Conference 2013: Javascript Insights

Multi-layered Defense

Page 29: HTML5 Developer Conference 2013: Javascript Insights
Page 30: HTML5 Developer Conference 2013: Javascript Insights

Multi-Layer Defense

Editor: syntax validation, linting

The earlier the better.

Pre-commit hooks: validation, linting, unit tests, code complexity thresholds, code coverage minimum

CI Server: validation, linting, unit tests, code complexity thresholds, code coverage minimum

Page 31: HTML5 Developer Conference 2013: Javascript Insights

Code Flowers

Page 32: HTML5 Developer Conference 2013: Javascript Insights

Application Structure

MyApp.create('MyApp.Person', { name: 'Joe Sixpack',  age: 42,

constructor: function(name) {},  walk: function(steps) {} run: function(steps) {}

});

{ objectName: 'MyApp.Person', functions: ['walk', 'run'], properties: ['name', 'age']}

Metadata

Page 33: HTML5 Developer Conference 2013: Javascript Insights

Final Words

Page 34: HTML5 Developer Conference 2013: Javascript Insights

Tools separate us

Page 35: HTML5 Developer Conference 2013: Javascript Insights

Good

Awesome

Even more awesome

Page 36: HTML5 Developer Conference 2013: Javascript Insights

Thank you!!!

@ariyahidayat@arobson

www.htmlhive.com ariya.ofilabs.com

speakerdeck.com/ariya