Top Banner
Jasper Moelker @jbmoelker
37

Voorhoede - Front-end architecture

May 19, 2015

Download

Technology

Jasper Moelker

Presented during Javascript MVC Amsterdam meetup, 29 Jan 2014: http://www.meetup.com/JavaScript-MVC-Meetup-Amsterdam/events/156767102/

At De Voorhoede (http://voorhoede.nl) I'm responsible for setting up new front-end projects in such a way that it's easy for teams to work with. This presentation explains how we structure these projects. The presentation includes some tips on structuring larger AngularJS projects.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Voorhoede - Front-end architecture

Jasper Moelker @jbmoelker

Page 2: Voorhoede - Front-end architecture

(ng) Architecturebest practices for setting up front-end / AngularJS projects

! warning: opinions ahead

Page 3: Voorhoede - Front-end architecture

de voorhoede

(NG) Architecture

Why care about front-end architecture? !

How to approach setting it up? !

modular structures !

Use tools that help you

image source: http://static.onemansblog.com/wp-content/uploads/2011/05/impossible-lego-03.jpg

Page 4: Voorhoede - Front-end architecture

Why care?aim: easy to use for (new) team members

Page 5: Voorhoede - Front-end architecture

de voorhoede

Why care?

• easy to understand

• easy to maintain

• easy to extend

• easy to re-use

• easy to deploy

• easy to distribute

Aim: easy to use for (New) team members

image source: http://www.registrycleaner.us.com

Page 6: Voorhoede - Front-end architecture

Ok, so how?approach: clear rules and standards

Page 7: Voorhoede - Front-end architecture

de voorhoede

Ok, so how?

• clear naming conventions

• clear directory structure

• clear dependency declarations

• clear code styles

• clear documentation (for what’s still unclear)

• clear tests & tasks for everything else

Approach: clear rules & standards

image source: http://www.carlosdinares.com

Page 8: Voorhoede - Front-end architecture

Think Modular-

Page 9: Voorhoede - Front-end architecture

de voorhoede

think modular

Atomic design by Brad Frost

source: http://bradfrostweb.com/blog/post/atomic-web-design/ see also: http://demo.pattern-lab.info/

Page 10: Voorhoede - Front-end architecture

de voorhoede

think modular

BEM blocks on smashing

source: http://coding.smashingmagazine.com/2012/04/16/a-new-front-end-methodology-bem/ see also: http://bem.info/

Page 11: Voorhoede - Front-end architecture

de voorhoede

think modular

source: https://github.com/angular/angular-seed/tree/master/app/js

used in ng tutorial

Page 12: Voorhoede - Front-end architecture

de voorhoede

think modular

source: http://briantford.com/blog/huuuuuge-angular-apps.html see also: https://github.com/angular/angularjs-batarang/

Brian ford on huuuuuge (5x) angular apps

used in batarang

Page 13: Voorhoede - Front-end architecture

de voorhoede

think modular

source: https://github.com/angular-app/angular-app/tree/master/client/src/app see also: https://github.com/ngbp/ngbp/tree/v0.3.1-release/src/app/home

read: http://cliffmeyers.com/blog/2013/4/21/code-organization-angularjs-javascript

ng app & ng boilerplate

Page 14: Voorhoede - Front-end architecture

de voorhoede

• Symfony 1: plugins

• Symfony 2: bundles (example on right)

• Web components

• Component.io

• Bower?

think modular

source: http://blog.solutionset.com/2012/09/14/easy-way-to-transform-a-twitter-oauth-library-into-a-symfony-2-bundle/

other frameworks / concepts

Page 15: Voorhoede - Front-end architecture

de voorhoede

think modular

Atomics

original image: http://bradfrostweb.com/blog/post/atomic-web-design/

Views

Components

Page 16: Voorhoede - Front-end architecture

de voorhoede

Think modular

App source structure

./source/ common/ <— atomics modules/ components/ <— re-usable components views/ <— unique views vendor/ <— third party modules app.js <— app core (config), include views bootstrap.js (+json) <— bootstrap app if supported index.html

Page 17: Voorhoede - Front-end architecture

de voorhoede

Atomics

typically no dependencies or only dependent on other atomics, examples:

• global css rules and variables (style guide)

• global assets like logo, fonts, icons

• high level (AngularJS) services: pub sub, rest service, transformers

• common (AngularJS) directives

• common (AngularJS) filters

elementary app rules & assets

source: http://www.heringinternational.com/de/beton/betoglass-4505.htm

Page 18: Voorhoede - Front-end architecture

de voorhoede

Atomics

structure atomics

common/ assets/ fonts/ images/ scss/ atomics/ _icons.scss mixins/ _mixin-name.scss directives/ view-box-directive.js filters/ services/ <— providers, services, factories rest-service.js

Page 19: Voorhoede - Front-end architecture

de voorhoede

Atomics in AngularJS

/** * @ngdoc directive * @name directives.viewBox.directive:viewBox * @description Supports using expression for SVG viewBox, by using `data-view-box` which sets * `viewBox` attribute. Code adapted from http://stackoverflow.com/a/14596319 * @example <doc:example> <doc:source> <svg data-view-box="{{ APP_VIEWPORT.viewBox }}"></svg> </doc:source> </doc:example> */ angular.module('directives.viewBox', []) // no dependencies .directive('viewBox', [ function () { 'use strict'; return { // no template, or other dependencies link: function (scope, element, attributes) { attributes.$observe('viewBox', function(value) { element.attr('viewBox', value); }); } }; } ]);

Page 20: Voorhoede - Front-end architecture

de voorhoede

Components

source: http://www.heringinternational.com/en/news&cmd=details&newsid=1179.htm

Re-usable encapsulated building blocks

• include structure (markup), presentation (style), behaviour (scripts), assets, docs, tests.

• important: declare dependencies

• in AngularJS use isolate scope to encapsulate component

Page 21: Voorhoede - Front-end architecture

de voorhoede

componentS

Structure component

modules/ components/ my-component/ media/ _my-component.scss / .less my-component-template.html my-component.js <— dependencies, config, ngdocs my-component-directive.js my-component-controller.js my-component-controller.test.js my-component-service.js my-component-service.test.js README.md

Page 22: Voorhoede - Front-end architecture

de voorhoede

Component in AngularJS

/** * @ngdoc overview * @name components.pager * @requires common/services.isPositiveInteger */ angular.module('components.pager', ['services.isPositiveInteger']); !/** * @ngdoc directive * @name components.pager.directive:pager */ angular.module('components.pager') .directive('pager', ['isPositiveInteger', function (isPositiveInteger) { 'use strict'; return { templateUrl: 'modules/components/pager/pager-template.html', replace: true, scope: { page: '=', itemsPerPage: '@', itemsTotal: '@' }, link: function (scope, element, attributes) {} } }]);

Page 23: Voorhoede - Front-end architecture

de voorhoede

Views

source: http://demavo.nl/literatuur/mondriaan.html

Unique compilation of components

in AngularJS

• uses ngView

• $routeProvider

• $stateProvider

Page 24: Voorhoede - Front-end architecture

de voorhoede

Views

Structure view

modules/ views/ my-view/ media/ _my-view.scss / .less my-view-view.html my-view.js <— dependencies, config, ngdocs my-view-directive.js my-view-controller.js my-view-controller.test.js README.md

Page 25: Voorhoede - Front-end architecture

de voorhoede

View in AngularJS

/** * @ngdoc overview * @name views.myView * @description My view module. * [detailed description of 'my view' module, which doesn't fit in this presentation] */ angular .module('views.myView', [ 'ngRoute', 'components.modal', 'components.pager', 'services.restService' ]) ! .config([ '$routeProvider', function ($routeProvider) { 'use strict'; $routeProvider .when('/view/my-view/:action', { templateUrl: 'modules/views/my-view/my-view-view.html', controller: 'MyViewController' }); } ]);

Page 26: Voorhoede - Front-end architecture

Code stylehelp keep your code clean & coherent

Page 27: Voorhoede - Front-end architecture

de voorhoede

Code quality tools

Configuration files in root

./ .csslintrc .jshintrc .jscs.json dubfind.cfg README.md

resources: csslint: http://csslint.net/ jshint: http://www.jshint.com/ jscs: https://github.com/mdevils/node-jscs dufind: https://github.com/sfrancisx/dupfind

Page 28: Voorhoede - Front-end architecture

Document your app-

Page 29: Voorhoede - Front-end architecture

de voorhoede

App documentation

…/ module.js index.ngdoc README.md !!!!!and use a style and / or code guide? for rules like use ‘ngMin proof syntax’.

README’s & NGDOCS

use ngdocs: https://github.com/m7r/grunt-ngdocs

Page 30: Voorhoede - Front-end architecture

Test your code-

Page 31: Voorhoede - Front-end architecture

de voorhoede

test your code

tests structure

./tests/ end-to-end/ helpers/ report/ csslint.xml jshint.xml karma.xml vendor/ <— eg. mocks end-to-end.js <— e2e and karma.js <— unit test config !test configs use bootstrap.json tests run locally and on Jenkins CI

Page 32: Voorhoede - Front-end architecture

Automatewrite tasks for repetitive actions

Page 33: Voorhoede - Front-end architecture

de voorhoede

Automate

Tasks structure

./Gruntfile.js —————>

./tasks/ grunt/ configuration/ task-name.js tasks/ task-name.js templates/ utilities/ phing/ java/ !we run tasks both locally and on server using Jenkins CI

module.exports = function (grunt) { 'use strict'; ! // Use `tasks/grunt/configuration/index.js`, // which reads package.json and loads all task configs: var config = require('./tasks/grunt/configuration')(grunt); grunt.config.init(config); ! // Load all npm installed grunt tasks. require(‘matchdep').filterDev('grunt-*') .forEach(grunt.loadNpmTasks); ! // load all project grunt tasks. grunt.task.loadTasks('tasks/grunt/tasks'); grunt.registerTask('default', [‘task-wizard']); };

source: http://gruntjs.com/img/grunt-logo.png

Page 34: Voorhoede - Front-end architecture

de voorhoede

Grunt Task wizard

source: https://gist.github.com/jbmoelker/8384456#file-task-wizard-js

1) Select task category

2) Select project task

3) Enter arguments

Result: New component created * new directory created * html, js, scss, readme files created * registers module in index files

Page 35: Voorhoede - Front-end architecture

de voorhoede

Automate

Develop task Deploy / distribute task// tasks/grunt/tasks/develop.js (non-ng project) !module.exports = function (grunt) { 'use strict'; grunt.registerTask( 'develop', 'Setup web dir for development and watch source', function (mode) { var tasks = [ 'compile-index:development', 'compile-html:development', 'copy:development', 'sass:development', 'concat:development' ]; if(mode !== 'no-watch'){ tasks.push('watch'); } grunt.task.run(tasks); } ); };

// tasks/grunt/tasks/deploy.js (ng-project) !module.exports = function (grunt) { 'use strict'; grunt.registerTask( 'deploy', 'Concatenates and minifies source files', function () { grunt.task.run([ 'clean:distribution', 'copy', 'ngtemplates', 'concat', 'uglify', 'clean:templates' ]); } ); };

Page 36: Voorhoede - Front-end architecture

de voorhoede

Think modular

App structure

./ distribution/ <— auto generated via ‘grunt deploy’ docs/ <— auto generated via ‘grunt docs’ source/ common/ <— atomics modules/ components/ <— re-usable components views/ <— unique views vendor/ app.js bootstrap.js index.html tasks/ <— task config, templates, utilities tests/ <— test config, e2e, helpers, reports web/ <— auto generated via ‘grunt develop’

Page 37: Voorhoede - Front-end architecture