Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories."— Presentation transcript:

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

2 Andrey Alpert andrey.alpert@dataart.com linkedin.com/in/andreyalpert

3 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

4 The way it should be ClientServerData MV* JS framework, Business logic, Mobile-ready layout Data storage. Treated like a black box. Thin-Server, REST, Event

5 The stack of technologies DRY 1 Declarative 2 Designers friendly 5 Dependency injection 4 Data binding 3

6 The stack of technologies UI Bootstrap 1 UI Router 2 … and others 5 NG Grid 4 UI Utils 3

7 Seed projects are sprouting like weeds They all suck

8 Organizing your app FilesLogicCode

9 BROS DON’T LET BROS ORGANIZE FILES BY TYPE – the angularjs bro code

10 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

11 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

12 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/ | | |- | |- assets/ | | |- | |- 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 12435

13 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 123 https://github.com/ngbp/ngbp by Josh Miller angular.module(‘app.user', [‘app.user.create’, ‘app.user.search’]); angular.module(‘app.user.create’, []);

14 Organizing your logic

15 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.

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

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

18 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

19 Business Models It is the very heart of your JavaScript application 1 It captures the behavior of the application in terms of its problem domain, independent of the user interface It describes a particular entity in the programming world in terms of data and state It encapsulates your application’s logic and data, provides an API to access and manipulate that data

20 Business Models angular.module('app', ['ngRoute']); module.factory(‘UserModel’, function (BaseModel) { var UserModel = BaseModel.$extend({ $initialize: function (firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } }); UserModel.prototype.getName = function () { return this.firstName + ' ' + this.lastName; }; return UserModel; }); module.controller('UserController', function ($scope, UserModel) { $scope.user= new UserModel('John', 'Doe'); }); {{ user.getName() }}

21 Collections A collection represents a group of models known as items 1 Collections are used to store, retrieve and manipulate data 2 Collections are wrappers above dynamic arrays and represent higher level of abstraction. 3

22 Creating Collection angular.module('app', ['ngRoute']); module.factory(‘UserCollection’, function (BaseCollection, UserCollection) { var UserCollection = BaseCollection.$extend({ $model: UserModel }); UserCollection.prototype.getNames = function () { var names = []; this.$getItems().forEach(function(item){ names.push(item.getName()); }); return names; }; return UserCollection; }); module.controller('UserController', function ($scope, UserCollection) { $scope.userCollection = new UserCollection; $scope.userCollection.$add('John', ‘Doe'); }); {{ name }}

23 Base Collection The BaseCollection class provides the basic interface to create a Collection class of your own. 1 Commonly used methods should be stored in BaseCollection $add $reset $getItems … 2 BaseCollection proxies to Underscore.js to provide iteration functions $forEach $last $find … 3

24 Resources A resource lets you interact with different data sources 1 In specific cases it can be a reusable proxy to HTTP/JSON endpoints. 2 Resources are injected into models and collections to provide the ability to send/retrieve data 3 module.service(‘UserResource’, function ($http) { this.list = function() { return $http.get(‘/some/endpoint/url’); }; this.update = function() { ………… }; this.delete = function() { ………… }; });

25 Organizing your code

26 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 12435 Can be found in any project Do NOT let it grow http://en.wikipedia.org/wiki/Technical_debt QUALITY

27 Code style Readability Good names Tabs/Spaces convention Clear logic Docs and comments 12435 jshint+stylish plato code painter editorconfig jscs eslint These are your friends Tools

28 Single responsibility File per each component 1 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() { }

29 IIFE Wrap components in an Immediately Invoked Function Expression 1 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() { } })();

30 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(MoviesSCollection) { return MoviesCollection.$loadItems(); } }); } })(); (function() { 'use strict'; angular.module(‘app’).controller(‘AvengersCtrl’, Avengers); function Avengers(resolvedMovies) { var ctrl = this; ctrl.moviesList = resolvedMovies; } })(); Really good for testing as you can mock injectable data

31 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

32 Test driven development TDD/BDD Better code understanding Release faster Motivation Reliability 12435 Long (hours) Medium (minutes) Fast (seconds) End 2 End API Services Database Headless Smoke tests unit tests Till first failed Remote Local. Stubs+Mocks Safe refactoring

33 Test driven development TDD/BDD Better code understanding Release faster Motivation Reliability 12435 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

34 Сode coverage Not tested area of application Dead code detection Acceptance threshold 70-90% Testing quality Reports 12435 Tools Istanbul JSCoverage Blanket coverage > 80% is AWESOME coverals.io codeclimate History and stats service

35 TDD with… + Cool for E2E tests I’m your test runner. The best one. These two guys are GOOD.

36 Laziness is the mother of INVENTION

37 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

38 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: '/*! */\n' }, build: { src: 'src/.js', dest: 'build/.min.js' } }); http://gruntjs.com http://gruntjs.com/plugins

39 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 operations 2 var gulp = require('gulp'); gulp.task('default', function() { // place code for your default task here }); http://gulpjs.com http://gulpjs.com/plugins

40 SUMMARY

41 THANKS.QUESTIONS?


Download ppt "Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories."

Similar presentations


Ads by Google