Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Nathaniel T. Schutta@ntschutta
Bulletproof JavaScript
It all started so quietly...
No avoiding it now...
JavaScript is a first class citizen.
What does that mean?
How do we create modern web applications?
Applications are changing.
How do we embrace that?
It isn’t the 90s anymore.
Remember alerts?
They aren’t a best practice anymore.
One could argue they are considered harmful.
Today we have tools!
IDEs can do more than syntax highlighting...
But it doesn’t end there.
Think of what you use in Java, C#, etc.
Testing, code coverage, build tools, code analysis...
Very rich toolset.
What about JavaScript?
JavaScript equivalents in nearly every case today.
In some cases, paradox of choice.
We’ll try and clear some of that up today.
We’re going to dig into testing and metrics today.
Goal is to whet your appetite.
Show you what can be done today.
Give you some ideas.
JSHint.
Certain mistakes can be caught automatically.
Static code analysis.
Akin to JSLint.
http://www.jslint.com
More configurable.
Finds common mistakes and defects.
Very few programs pass ;)
Highly configurable.
Can configure inline, via file or in package.json.
Configuration is JSON.
Tune via ‘enforcing’ and ‘relaxing’ options.
Enforcing makes JSHint more strict...
Relaxing does the opposite.
Dozens and dozens of configuration options.
http://www.jshint.com/docs/options/
Can also hide individual warnings if needed.
Defaults are pretty good.
But may want to turn a few more things on.
Curly braces are optional on single line blocks.
But that’s a great way inject sneaky bugs.
curly: true
JavaScript has two sets of equality operators.
==, != ===, !==
The first set coerce values.
Can give some odd results.
eqeqeq: true
Empty blocks aren’t harmful…
But probably indicate some cruft in the code.
noempty: true
Quote marks should be consistent in your code…
But it is easy to mix single and double quotes.
We have a couple of options to choose from.
quotmark: true
Enforces consistency.
But you can force a specific style if you prefer.
quotmark: “single” quotmark: “double”
Undeclared variables are easy in JavaScript.
Probably a typo. Or worse.
undef: true
Sometimes undefined vars comes from other file.
We can tell JSHint that.
predef: ["foo", "bar"]
Sometimes we declare things we don’t use.
Not generally harmful…
But indicates some cruft.
unused: true
JavaScript is very forgiving.
Maybe too forgiving.
Many developers leverage “strict mode”.
Throws certain errors, prohibits some syntax.
Invoking it is simple, but it is easy to forget.
strict: true
But that’s not it!
Act now…
Bitwise operators are rare in JavaScript…
You can flag them.
bitwise: true
JavaScript lets you augment native objects.
Array missing something? You can add it!
Helpful…but at a cost.
You can block it.
freeze: true
Have a preferred indent level? There’s a flag for that.
indent: 4
JavaScript appears to have block scope…but it doesn’t.
Global or function. That’s it.
latedef: true
Can also set various max lengths.
You can set the maximum number of:
Parameters, nesting depth, function length…
Even line length.
maxparams, maxdepth, maxstatements, maxlen
Can also set a maximum cyclomatic complexity.
Number of paths through a code base.
Smaller is better!
maxcomplexity: 2
You can ask JSHint to ignore a chunk of code.
/* jshint ignore:start */ /* jshint ignore:end */
Be careful with that…
You can also relax a number of rules.
Use with caution.
Can also tell JSHint about certain environments…
Browser, Node, etc.
This will define certain global variables.
Think console.
Installed via npm.
JSLint License...MIT with one addition:
“This Software shall be used for Good, not Evil.”
http://www.jshint.com
Configuration options.
There are a lot of options.
Which ones should you turn on? Relax?
It depends!
Is this an existing project?
Or greenfield?
Tempting to crank all the knobs up to 11.
Existing projects probably have some cruft.
Don’t overwhelm the team with warnings!
Easy to get discouraged.
“We have so many warnings…”
Fixing 10 or 20 hardly makes a dent.
Easy to miss when you add another one…
Start small.
Expect some…discussion around which rules to use.
Pick one or two.
Turn them on.
Should result in a manageable set of warnings.
Fix them!
An iteration or two later, add another rule or two.
Rinse, repeat.
“Ratchet up.”
Over time, you’ll have a very complete set.
And a clean code base.
With a new code base, it is easier to start big.
Start clean, stay clean.
Don’t be afraid to tweak!
The warnings are there to help, not hurt.
Plato.
Static analysis tool.
Source code visualizer, complexity analyzer.
Leverages JSHint and complexityReport.js.
Cyclomatic complexity, line count, param count...
Halstead metrics, maintainability index.
Includes detailed view.
Can execute from the command line.
Or via Grunt.
plato -r -d report js
You can also run it against your test code…
You can tweak the rules.
You can point to a JSHint option file.
Or you can turn off JSHint.
Still has that new software smell.
Installed via npm.
MIT License.
https://github.com/es-analysis/plato
Jasmine.
We must test our code.
BDD JavaScript testing framework.
More readable?
Doesn’t require the DOM or other libraries.
Suites with specs.
Set of matchers.
Can create custom matchers.
Group related specs with ‘describe’.
Describe blocks can be nested.
Includes beforeEach and afterEach for setup/teardown.
Specs and blocks can be disabled...
Don’t forget to turn them back on!
Includes spies aka test doubles.
Can mock out the JavaScript clock.
Includes a waitFor to test asynchronous cases.
Runs in any JavaScript environment.
Include Jasmine file, page is now a runner.
Results read like a specification.
At least that’s the idea ;)
Download the library.
MIT License.
http://jasmine.github.io
Karma.
Tests need to be executed.
JavaScript test runner.
Created by AngularJS team.
Originated as MS thesis.
https://github.com/karma-runner/karma/raw/master/thesis.pdf
Quick feedback.
Works with several testing frameworks.
Works with continuous integration servers.
Change a file, Karma runs the tests.
Spawns a web server.
Results displayed at the command line.
Can also point a browser at the Karma web server.
Allows for mobile browser results.
Ships with Chrome and PhantomJS.
Plugins for all major browsers.
Can also point to custom browsers if needed.
Can launch from the command line.
karma start karma.conf.js
Or from Grunt.
Requires a bit of work…
Install grunt-karma.
And anything your Karma configuration needs.
Like karma-jasmine.
And whatever browser(s) you use.
One other options.
npm scripts
In package.json file, add a scripts element.
Several options.
"test": "karma start config/karma.conf.js"
Still has that new software smell.
Installed via npm.
MIT License.
http://karma-runner.github.io/0.10/index.html
Phantom.
Browser testing can be slow and tedious.
Headless WebKit.
Headless testing in a CI environment.
Full DOM, CSS selector, JSON, Canvas and SVG.
Not itself a test runner...
Works with Jasmine, Mocha, QUnit, etc.
Several built in, most others have a 3rd party runner.
Can also capture screen shots.
Supports PNG, JPEG, GIF and PDF.
Can be used for network monitoring.
Page automation - can even use jQuery.
Open a page, click a button...
Tell Karma to use Phantom rather than Chrome.
Of course we can run all of this from Grunt too.
Grunt plugins are your friend!
grunt-contrib-jasmine
Runs Jasmine tests heedlessly via PhantomJS.
Load the task, add the template, configure…
Various platform dependent installs.
BSD License.
http://phantomjs.org
Istanbul.
We need to know what we’ve tested...
And what we haven’t.
Code coverage tool.
Bugs tend to lurk where there are no tests.
All JavaScript.
Tracks statement, branch and function.
Instrument on the fly.
Can run at the command line or as part of build.
HTML and LCOV reports.
Still has that new software smell.
Installed via npm.
BSD License.
http://gotwarlost.github.io/istanbul/
Is that all of them?
Nope.
Nearly every tool we looked at has alternatives.
Don’t like some of these?
Great, use what works for your team!
Perform a time boxed eval.
But use something!
Many of these tools are very new.
Expect some volatility.
Can’t treat JavaScript as a toy language today.
You don’t need to adopt every one of these today.
Pick your pain point.
Introduce one or two tools.
Ratchet up.
After a few weeks or months, add another.
Rinse repeat.
We’ve come a long way!
JavaScript is a first class citizen.
We have the tools to prove it.
No excuses.
Nathaniel T. Schutta@ntschutta
Thanks!