Code style
1
Is all code intention-revealing?
What?
All code should be easy to understand for other developers
Why?
To make sure the code can be updated, refactored and maintained by others if needed
2
Is all code linted/hinted?
What?
All code should be syntactically correct
Why?
To avoid unpredictable errors
3
Is `controller as` syntax used?
What?
Use controllerAs
Use bindToController
Why?
Avoid pitfalls from scope soup
Target outer scopes easily from within inner scopes
4
Is DOM manipulation handled only by directives?
What?
DOM manipulation should only happen in directives
Use the element available in the directive compile and link function to manipulate the DOM
No DOM manipulation from controllers or services
Why?
Angular is declarative with directives attached to elements. The directive then provides access via the compile or link element to this DOM element
5
Are names prefixed with `$ ` avoided?
What?
Names of variables, properties and methods should not start with $
Why?
The $ prefix is reserved for AngularJS internals
6
Is direct use of globals avoided?
What?
Create services to wrap globals
Use dependency injection to inject global wrappers
Why?
Prevents unpredictable application behavior when global is not available
Easier to test: allows you to mock global
7
Are AngularJS specific directives put after standard attributes in templates?
What?
Put AngularJS specific directives after standard attributes
Why?
Easier to read and maintain your code
8
Are built-in AngularJS dependencies injected before custom ones?
What?
Inject built-in AngularJS dependencies before customer ones
Example: function($rootScope, $timeout, MyDependency)
Why?
Easier to read and maintain your code
10
Are controllers named correctly?
What?
UpperCamelCase + Ctrl or UpperCamelCase + Controller
Example: MyCtrl or MyController
Why?
Naming convention
11
Are directives named correctly?
What?
lowerCamelCase
Example: myDirective
Use scope instead of $scope in link function
Use custom prefix to prevent name collisions with third-party libraries
Don’t use ng prefix as it is reserved for AngularJS
Why?
Naming convention
12
Are filters named correctly?
What?
lowerCamelCase
Example: myFilter
Why?
Naming convention
13
Are services named correctly?
What?
lowerCamelCase
Example: myService
UpperCamelCase if service is a Constructor
Example: MyContrstructorClassService
Why?
Naming convention
14
Are factories named correctly?
What?
lowerCamelCase
Example: myFactory
Why?
Naming convention
15
Are built-in AngularJS directives used whenever possible?
What?
Use ng-src instead of src, ng-hrefinstead of href, ng-styleinstead of style, etc. when dynamic values are passed
Why?
They make sure markup remains valid, even when expression value is not available yet
They are well-written and tested
16
Are built-in AngularJS services used whenever possible?
What?
Use $ services provided by AngularJS whenever possible
Examples: $timeout, $interval, $http, …
Why?
These services are designed to work well with the $digest cycle
They are well-written and tested
17
Is ng-cloak used to prevent content from flashing
What?
Use ng-cloak to initially hide elements that are only visible under certain conditions
Why?
Prevents content flashing when page is loaded
18
Is console.log() avoided?
What?
use $log service
use $log.debug() to write debug messages to the console
Why?
allows you to turn off debug logging in production
19
Is code minification safe?
What?
Use array notation or $inject notation or use ng-annotate
Why?
Code will break when minified if not written in a way that supports minification
Architecture
2
Do directives communicate correctly?
What?
Never rely on scope inheritance e.g. $scope.$parent
Use directive controllers and require to let directives communicate
Why?
The scope hierarchy may change, breaking your code
3
Is business logic defined in services?
What?
Business logic should be defined in services, not in controllers
Why?
Business logic is centralized and reusable
Services are really easy to test
4
UI-Router: has a default route been configured?
What?
Use $urlRouterProvider.otherwise() to specify the default route in case no route definition matches the request
Why?
To gracefully handle requests that do not match to a route definition
5
ngRoute: has a default route been configured?
What?
Use $routerProvider.otherwise() to specify the default route in case no route definition matches the request
Why?
to gracefully handle requests that do not match to a route definition
6
ngRoute: are route errors handled properly?
What?
use a $routeChangeError event listener to handle routing errors
Why?
To gracefully handle routing errors
7
UI-Router: are state change errors handled properly?
What?
use a $stateChangeError event listener to handle routing errors
Why?
to gracefully handle errors that occur during state transition (e.g. when a resolve fails)
8
Are exceptions handled properly?
What?
decorate the $exceptionHandler service to handle uncaught exceptions
Why?
To gracefully handle uncaught exceptions
Security
1
Is Strict Contextual Escaping enabled?
What?
Make sure SCE is enabled
Use $sce service to explicitly tell AngularJS which content can be marked as safe for a context
As of version 1.2, AngularJS ships with SCE enabled by default.
Why?
To deal with content that can not be trusted
With SCE disabled, your application allows a user to render arbitrary data creating security vulnerabilities
2
UI-Router: are private parts of application properly protected?
What?
Use border states to protect private areas in your application
Use $stateChangeStart event handler to control access
Why?
To restrict access to private areas in your application
To make sure the states cannot be accessed by guessing the url's
3
Is there a server-side template engine involved?
What?
Don't use a server-side template engine for building angular templates
Why?
XSS prevention of the server-side template don't avoid injection of angular expressions
Violation of this rule can result in a XSS vulnerability
This issue is called "client-side template injection"
4
Is user input used for template generation or in watch expressions?
What?
User input must not be used for template generation: $compile, $parse and $interpolate
User input must not be used for expressions inside the following functions: watches, $eval, $apply and not in the orderBy pipe
Why?
Violation of this rule can result in a XSS vulnerability
Accessibility
1
Is ngAria included?
What?
Include the ngAria module as a dependency
Why?
To convey state or semantic information about the application for users of assistive technologies, such as screen readers
Performance
1
Are scripts at bottom of the document?
What?
<script> elements should be as low as possible in document
Why?
Improves initial rendering speed
2
Are styles in HEAD?
What?
Stylesheets should be in the document <head>
Why?
Improves initial rendering speed
3
Is expensive logic avoided in filters?
What?
Filter logic should be lightweight
Why?
Filters are called often during $digest loop so if they are slow, they will slow down your application
4
Is filtering logic handled in controller if needed?
What?
Filtering can be done in controller if the result is not affected by every $digest cycle
Why?
To control manually when the filter should run instead of with every $digest cycle
5
Are expensive operations cached?
What?
Cache operations that are expensive (e.g. CPU or bandwidth intensive)
Why?
Optimizes speed by avoiding repetition of expensive operation
6
Are complex expressions avoided in templates?
What?
Complex logic should be handled in controller or service
Why?
View expressions are evaluated many times during $digest cycles
Putting the logic in a controller or services allows you to cache the result
7
Is one-time binding used where possible?
What?
Use {{ :: expression }} for content that does not change after initialization
Why?
AngularJS will stop watching the expression as soon as it evaluates to a non-null value
8
Is logic in watchers kept as simple as possible?
What?
Keep computations in $watch as simple as possible
Example: watch data.property instead of deep watching data
Why?
Watchers are evaluated many times during $digest cycles so keeping them fast results in better performance
9
Is $watchCollection used instead of deep watch where possible?
What?
Use $watchCollection instead of a deep watch for collections
Why?
$watchCollection performs a shallow equality check of the result of the watched expression and its previous value, resulting in better performance
10
Is `$applyAsync` used when possible?
What?
Use $scope.$applyAsync()
Configure $httpProvider to use $applyAsync: $httpProvider.useApplyAsync(true);
Why?
To reduce number of $digest cycles when expressions are evaluated around the same time
11
Do timers skip `$digest` cycle when possible?
What?
Pass false as third parameter to $timeout when no watched variables are impacted by its callback
Why?
To skip unnecessary $digest cycles
12
Are resources cleaned up when scope is destroyed?
What?
use $scope.$on(‘$destroy’, fn) to clean up resources such as timers and intervals
Why?
resources that are not cleaned up can chew up memory and CPU
every time the scope is recreated (e.g. when page is visited again and again) the problem grows bigger
13
Are templates bundled with main JavaScript file?
What?
Bundle your templates with your scripts using tools like grunt-html2js or gulp-html2js
Why?
Reduce number of network requests, especially when a large number of templates needs to be downloaded
14
Is ngModelOptions used where possible?
What?
Use ngModelOptions to manually control when $digest cycle should run
Why?
To prevent unnecessary $digest cycles
Created by @jvandemo
Powered by HarpJS
Hosted on Surge
Code on GitHub