building scalable applications with angularjs and modern applications infrastructure based on real...
TRANSCRIPT
![Page 1: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/1.jpg)
Building scalable applications with AngularJS
and modern applications infrastructure
Based on real life stories
![Page 3: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/3.jpg)
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 AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/4.jpg)
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 AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/5.jpg)
The stack of technologies
DRY1
Declarative2
Designers friendly5
Dependency injection4
Data binding3
![Page 6: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/6.jpg)
The stack of technologies
UI Bootstrap1
UI Router2
… and others5
NG Grid4
UI Utils3
![Page 7: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/7.jpg)
Seed projects are sprouting like weeds
They all suck
![Page 8: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/8.jpg)
Organizing your app
Files Logic Code
![Page 9: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/9.jpg)
BROS DON’T LET BROSORGANIZE FILES
BY TYPE– the angularjs bro code
![Page 10: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/10.jpg)
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 11: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/11.jpg)
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 12: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/12.jpg)
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 13: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/13.jpg)
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 14: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/14.jpg)
Organizing your logic
![Page 15: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/15.jpg)
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 16: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/16.jpg)
That's great!Now you know exactly how to break up your code
![Page 17: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/17.jpg)
UNTIL…
That's great!Now you know exactly how to break up your code
![Page 18: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/18.jpg)
The problem with controllers
Common functionalityList 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 19: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/19.jpg)
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
![Page 20: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/20.jpg)
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');});
<span>{{ user.getName() }}</span>
![Page 21: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/21.jpg)
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
![Page 22: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/22.jpg)
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');});
<span ng-repeat=“userCollection.getNames() as name”>{{ name }}</span>
![Page 23: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/23.jpg)
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
![Page 24: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/24.jpg)
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() { ………… };});
![Page 25: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/25.jpg)
Organizing your code
![Page 26: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/26.jpg)
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 27: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/27.jpg)
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 28: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/28.jpg)
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 29: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/29.jpg)
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 30: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/30.jpg)
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
![Page 31: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/31.jpg)
RED(Fail)
GREEN(Pass)
REFACTOR
1. Write a test that fails
2. Make only enough code for it to pass
3. Improve code quality
REPEATPROCESS
![Page 32: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/32.jpg)
Test driven development
TDD/BDD
Better code understanding
Release faster
Motivation
Reliability
1
2
4
3
5
Long (hours)
Medium (minutes)
Fast (seconds)
End 2 End
APIServicesDatabaseHeadless
Smoke testsunit tests
Till first failed
Remote
Local.Stubs+Mocks
Safe refactoring
![Page 33: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/33.jpg)
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 AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/34.jpg)
С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.iocodeclimate
History and stats service
![Page 35: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/35.jpg)
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 AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/36.jpg)
Laziness is the mother
of INVENTION
![Page 37: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/37.jpg)
What tasks to automate
SourceConcatenateUglifySourceMaps
WatchLiveReloadRebuildServe
PreprocessLESSSASSCompass
TestKarmaMochaCoverage
AssetsTemplatesHTML processingImages optimization
CustomChangeLogNotificationsconsole.debug
![Page 38: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/38.jpg)
Task runner: grunt
FILE BASEDGood for file operations like copy/move/save. Configuration is over the code
1
TONS OF PLUGINSMany 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 AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/39.jpg)
The streaming build system: gulp
Fast (seconds)
EASY TO USEBy preferring code over configuration, gulp keeps simple things simple and makes complex tasks manageable.
1
STREAM BASEDMuch 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
![Page 40: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/40.jpg)
SUMMARY
![Page 41: Building scalable applications with AngularJS and modern applications infrastructure Based on real life stories](https://reader035.vdocuments.us/reader035/viewer/2022062717/56649e205503460f94b0c659/html5/thumbnails/41.jpg)
THANKS.QUESTIONS?