46
Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories

Building scalable applications with angular js

Embed Size (px)

Citation preview

Page 1: Building scalable applications with angular js

Building scalable applications with AngularJSand modern applications infrastructure

Based on real life stories

Page 3: Building scalable applications with angular js

The way it was…

Mixed client server leads to increased complexity

Presentation logic will require a lot of interactions with the server

Not a real application, just another website

Page 4: Building scalable applications with angular js

The way it should be

Client Server Data

MV* JS framework, Business logic, Mobile-ready layout

Data storage. Treated like a black box.

Thin-Server, REST, Event

Page 5: Building scalable applications with angular js

The stack of technologies

Page 6: Building scalable applications with angular js

The stack of technologies

Page 7: Building scalable applications with angular js

The stack of technologies

DRY1

Declarative2

Designers friendly5

Dependency injection4

Data binding3

Page 8: Building scalable applications with angular js

The stack of technologies

UI Bootstrap1

UI Router2

… and others5

NG Grid4

UI Utils3

Page 9: Building scalable applications with angular js

Seed projects are sprouting like weeds

They all suck

Page 10: Building scalable applications with angular js

Organizing your app

Files Logic Code

Page 11: Building scalable applications with angular js

BROS DON’T LET BROSORGANIZE FILES BY TYPE

– the angularjs bro code

Page 12: Building scalable applications with angular js

Organizing by type

Organize by services, controllers, views, etc.1

One module per directory.2

Directories become bloated.4

Poor control over your DI configuration.3

Page 13: Building scalable applications with angular js

Folders-by-Feature Structure

Organize by component / feature.1

Directory structure mirrors app structure.2

Can create angular modules that more accurately reflect injection dependencies.

4

Easier to extract / share components.3

Page 14: Building scalable applications with angular js

Folders-by-Feature Structure

All files related to a feature live together (html, css, tests).

Application-level files live directly under app/

Each section / page of the app has its own folder under app/

Things used throughout the app live under common/

Files related to the app live outside of app/

!super-dooper-project/ |- src/ | |- app/ | | |- <app logic> | |- assets/ | | |- <static files> | |- common/ | | |- components/ | | |- services/ | |- less/ | | |- main.less |- bower_components/ | |- bootstrap_components/ | |- angular-bootstrap/ | |- bootstrap/ |- karma/ |- .bowerrc |- bower.json |- build.config.js |- Gruntfile.js |- module.prefix |- module.suffix |- package.json

1

2

4

3

5

Page 15: Building scalable applications with angular js

Application layout

Modules should mirror URL

Submodules live near main module

Submodules listed as dependencies to main module

src/ |- app/ | |- user/ | | |- create/ | | |- search/ | | |- user.js | | |- user.ctrl.js | | |- user.less | | |- user.spec.js | | |- user.tpl.html

1

2

3

https://github.com/ngbp/ngbp by Josh Miller

angular.module(‘app.user', [‘app.user.create’, ‘app.user.search’]);

angular.module(‘app.user.create’, []);

Page 16: Building scalable applications with angular js

Organizing your logic

Page 17: Building scalable applications with angular js

Angular talks about…

Services

are app-‐wide injected

singletons.

Controllers

are bridge between template and the rest of your application logic.

Directives

are encapsulation of some widget or DOM

element behavior.

Filters

are simple output formatting

functions.

Page 18: Building scalable applications with angular js

That's great! Now you know exactly how to break up your code

Page 19: Building scalable applications with angular js

UNTIL…

That's great! Now you know exactly how to break up your code

Page 20: Building scalable applications with angular js

The problem with controllers

Common functionality List pages, properties pages, etc.1

Very complicated views can end up having multi-thousand line controllers.2

How can you break up logic that is going to be used in many controllers?3

Page 21: Building scalable applications with angular js

Option 1 – inheritance

What is it? Traditional OOP inheritance e.g. BaseListController → sorting, paging, filtering…

Cons Hierarchy can become too deep and confusing Some controllers in our app are 5 levels deep Some logic doesn't fit neatly into a generic parent Imperfect encapsulation

Page 22: Building scalable applications with angular js

Option 2 – mixins

What is it? Object whose properties are mixed into another.

Cons It becomes unclear where code comes from. Mixins could potentially conflict with or overwrite each other. Mixin is tightly coupled to the mixed-‐into object.

!  angular.extend(ctrl,  ListMixin);    

Page 23: Building scalable applications with angular js

Option 3 – object composition

What is it? Traditional object composition that takes advantage of Angular's dependency injection.

Cons Can’t inject the objects themselves (﴾until angular 2.0)﴿

!  ctrl.listManager  =  $injector.instantiate(app.ListManager,  {});    

Pros Better encapsulation Easier reuse Forces more coherent API design

Page 24: Building scalable applications with angular js

Organizing your code

Page 25: Building scalable applications with angular js

Technical debt

Tests will be in the next release

Code entropy: “if touch that code everything will break”

Docs? My code is state of art!

TODO/FIXME statements

Let’s just copy/paste for now

1

2

4

3

5

Can be found in any projectDo NOT let it grow

http://en.wikipedia.org/wiki/Technical_debt

QUALITY

Page 26: Building scalable applications with angular js

Code style

Readability

Good names

Tabs/Spaces convention

Clear logic

Docs and comments

1

2

4

3

5

!• jshint+stylish • plato • code painter • editorconfig • jscs • eslint

These are your friends

Tools

Page 27: Building scalable applications with angular js

Single responsibility

File per each component1

• Gives the most control over how the injector is configured • Much easier to extract code into shared components • When testing, only have to load specific module under test

angular.module('app', ['ngRoute']);

angular.module(‘app’).controller('SomeController', SomeController); ! function SomeController() { }

angular.module(‘app’).factory('someFactory', SomeFactory); ! function SomeFactory() { }

Page 28: Building scalable applications with angular js

IIFE

Wrap components in an Immediately Invoked Function Expression1

• An IIFE removes variables from the global scope. • Protects us from having collisions of variables and many global variables.

(function() { 'use strict'; angular.module(‘app’) .controller('SomeController', SomeController); ! function SomeController() { } })();

Page 29: Building scalable applications with angular js

ControllerAs Controller Syntax

• Use the controllerAs syntax over the classic controller with $scope syntax. • The controllerAs syntax uses this inside controllers which gets bound to

$scope • controllerAs is syntactic sugar over $scope. You can still bind to the View

and still access $scope methods. • Use a capture variable for this when using the controllerAs syntax.

(function() { 'use strict'; angular.module(‘app’) .controller('SomeController', SomeController); ! function SomeController() { var ctrl = this; ctrl.name = {}; ctrl.sendMessage = function() { }; } })();

Page 30: Building scalable applications with angular js

Resolve promises for your controllers

A controller may require data before it loads. That data may come from a promise via a custom factory or $http. Using a route resolve allows the promise to resolve before the controller logic executes, so it might take action based on that data from the promise.

(function() { 'use strict'; angular.module(‘app’).config(myConfig); ! function myConfig($routeProvider) { $routeProvider .when('/avengers', { templateUrl: 'avengers.html', controller: 'AvengersCtrl', controllerAs: 'av', resolve: { resolvedMovies: function(movieService) { return movieService.getMovies(); } } }); } })();

(function() { 'use strict'; angular.module(‘app’).controller(‘AvengersCtrl’, Avengers); ! function Avengers(resolvedMovies) { var ctrl = this; ctrl.moviesList = resolvedMovies.data; } })();

Really good for testing as you can mock injectable data

Page 31: Building scalable applications with angular js

RED (Fail)

GREEN (Pass)REFACTOR

1. Write a test that fails

2. Make only enough code for it to pass

3. Improve code quality

REPEAT PROCESS

Page 32: Building scalable applications with angular js

Test driven development

TDD/BDD

Better code understanding

Release faster

Motivation

Reliability

1

2

4

3

5

Long (﴾hours)﴿Medium (﴾minutes)﴿

Fast (﴾seconds)﴿UIEnd 2 End

API Services Database Headless

Smoke tests unit tests

Till first failed

Remote

Local. Stubs+Mocks

Safe refactoring

Page 33: Building scalable applications with angular js

Test driven development

TDD/BDD

Better code understanding

Release faster

Motivation

Reliability

1

2

4

3

5

Fast (seconds)

it('should have Avengers controller', function() { //TODO }); ! it('should find 1 Avenger when filtered by name', function() { //TODO }); ! it('should have 10 Avengers', function() {} //TODO (mock data?) }); ! it('should return Avengers via XHR', function() {} //TODO ($httpBackend?) }); ! // and so on

Page 34: Building scalable applications with angular js

Сode coverage

Not tested area of application

Dead code detection

Acceptance threshold 70-90%

Testing quality

Reports

1

2

4

3

5

Tools

Istanbul JSCoverage Blanket

coverage > 80% is AWESOME

coverals.io codeclimate

History and stats service

Page 35: Building scalable applications with angular js

TDD with…

+

Cool for E2E tests

I’m your test runner. !

The best one.

These two guys are GOOD.

Page 36: Building scalable applications with angular js

Laziness is the mother

of INVENTION

Page 37: Building scalable applications with angular js

What tasks to automate

Source Concatenate Uglify SourceMaps

Watch LiveReload Rebuild Serve

Preprocess LESS SASS Compass

Test Karma Mocha Coverage

Assets Templates HTML processing Images optimization

Custom ChangeLog Notifications console.debug

Page 38: Building scalable applications with angular js

Task runner: grunt

FILE BASED Good for file operations like copy/move/save. Configuration is over the code

1

TONS OF PLUGINS Many of the tasks you need are already available as Grunt Plugins, and new plugins are published every day.

2

grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), uglify: { options: { banner: '/*! <%= pkg.name %>*/\n' }, build: { src: 'src/<%= pkg.name %>.js', dest: 'build/<%= pkg.name %>.min.js' } } });

http://gruntjs.com

http://gruntjs.com/plugins

Page 39: Building scalable applications with angular js

The streaming build system: gulp

Fast (seconds)

EASY TO USE By preferring code over configuration, gulp keeps simple things simple and makes complex tasks manageable.

1

STREAM BASED Much more faster then Grunt for file-‐content processing operations2

var gulp = require('gulp'); ! gulp.task('default', function() { // place code for your default task here });

http://gulpjs.com

http://gulpjs.com/plugins

Page 40: Building scalable applications with angular js

Deployment

Page 41: Building scalable applications with angular js

Continues integration

Builds history

Last successful/failed build

Multiple environments

Parallel builds

Rollback

1

2

4

3

5

Fast (seconds)

Page 42: Building scalable applications with angular js

Server as platform

Customizable stack and environment

Own services to use

Infrastructure

Need for DevOps

1

2

4

3

Fast (seconds)

Amazon, Digital Ocean or Rackspace

Page 43: Building scalable applications with angular js

Platform as a Service

Takes care of infrastructure for you

Updating packages and installing security patches

Technical support 24/7

Reliability and Monitoring

1

2

4

3AzureHeroku Nodejitsu CloudFoundry

Page 44: Building scalable applications with angular js

Docker

Your own PaaS

Open Source

Ready to use stacks

Easy Scale

Easy to migrate

1

2

4

3

5

Deis Flynn Tsuru Octohost

Tools

Application + Platform = Container

Page 45: Building scalable applications with angular js

SUMMARY

Page 46: Building scalable applications with angular js

THANKS. QUESTIONS?