Slide 1

Slide 1 text

JavaScript Insights Tools for Improving JS Code Quality Ariya Hidayat @ariyahidayat HTML5 Developer Conference San Francisco, October 22, 2013 Ann Robson @arobson

Slide 2

Slide 2 text

car salesman Ariya Ann

Slide 3

Slide 3 text

Why JavaScript code quality tools?

Slide 4

Slide 4 text

It’s how we work together.

Slide 5

Slide 5 text

And it’s how we level up.

Slide 6

Slide 6 text

varied... JavaScript Tools some to be developed…. ALL are open source ? $0 $0 $0 $0 ?

Slide 7

Slide 7 text

Power(ful) tools

Slide 8

Slide 8 text

Linter Code Coverage Cyclomatic Complexity

Slide 9

Slide 9 text

Linter JSHint http://jshint.com Enforces style guide Team standards: .jshintrc

Slide 10

Slide 10 text

Code Coverage Istanbul http://ariya.ofilabs.com/2012/12/javascript-code-coverage-with-istanbul.html http://gotwarlost.github.io/istanbul/

Slide 11

Slide 11 text

If you think JSLint hurts your feelings, wait until you use Istanbul @davglass from Yahoo!

Slide 12

Slide 12 text

Code Complexity if (true) "foo"; else "bar"; Control Flow Graph 6 edges 6 nodes 1 exit Cyclomatic Complexity = 2 JSComplexity http://jscomplexity.org

Slide 13

Slide 13 text

Complexity Visualization https://github.com/jsoverson/plato Plato Continuous Delivery for JavaScript Applications Jarrod Overson Room E-131 Wed 11.40am

Slide 14

Slide 14 text

Pre-commit Hooks May include all tools previously mentioned: - linting - code coverage - code complexity Also, - validation: esvalidate - custom

Slide 15

Slide 15 text

Demos

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Pre-commit Hooks Escape! git commit -n

Slide 18

Slide 18 text

Composable Tools

Slide 19

Slide 19 text

Stray logging Strict mode violations Unused variables Nested ternary conditionals Polluting variables Boolean traps

Slide 20

Slide 20 text

{ 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; Esprima http://esprima.org

Slide 21

Slide 21 text

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 }); }

Slide 22

Slide 22 text

Strict Mode Validator 'use strict'; block = { color: 'blue', height: 20, width: 10, color: 'red' }; Duplicate data property in object literal not allowed in strict mode http://ariya.ofilabs.com/2012/10/validating-strict-mode.html

Slide 23

Slide 23 text

Polluting Variables var height; // some fancy processing heigth = 200; Leaks to global test.js:3 heigth = 200; ^ LeakError: global leak detected: heigth https://github.com/kesla/node-leaky http://ariya.ofilabs.com/2012/11/polluting-and-unused-javascript-variables.html

Slide 24

Slide 24 text

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 processing heigth = 200; Declared but not used

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

“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);

Slide 27

Slide 27 text

Future linting ESLint How we might collect the tools we make https://github.com/nzakas/eslint

Slide 28

Slide 28 text

Multi-layered Defense

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Code Flowers

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Final Words

Slide 34

Slide 34 text

Tools separate us

Slide 35

Slide 35 text

Good Awesome Even more awesome

Slide 36

Slide 36 text

Thank you!!! @ariyahidayat @arobson www.htmlhive.com ariya.ofilabs.com speakerdeck.com/ariya