Slide 1

Slide 1 text

Ustream vs Legacy @matenadasdi

Slide 2

Slide 2 text

Ustream basics 80.000.000 visitors / month 5.000.000+ viewer hours on tough days

Slide 3

Slide 3 text

Legacy is not bad code, it’s just old or over-iterated

Slide 4

Slide 4 text

Everyone starts in the dark… but there is always light in the end of the tunnel

Slide 5

Slide 5 text

Our goal was to achieve more stability and scalability in our frontend codebase

Slide 6

Slide 6 text

Our situation was (like every frontend codebase some years ago) no tests no modules all-in-one feature based class system poor abstraction JSLint as “code quality tools”

Slide 7

Slide 7 text

It’s a new ERA it’s a heaven of tools and new solutions for frontend developers nowadays

Slide 8

Slide 8 text

we had 5 stages in our long journey it may help or inspire you too

Slide 9

Slide 9 text

Structure

Slide 10

Slide 10 text

separate business logic from its representation easy isolation dependency injection we had to create / use a new structure There are some must-have things for testing…

Slide 11

Slide 11 text

not the framework, the way of thinking matters

Slide 12

Slide 12 text

always think in layers with separated responsibilities

Slide 13

Slide 13 text

Sync Socket (full-duplex) Async get data set data DOM AJAX WebStorage Cookies Socket Ustream Flash API Longpoll Embeds Views manipulates events Controllers control notify Logics Models get data set data

Slide 14

Slide 14 text

our new small framework is under 10kb but we had millions of lines written in an old style

Slide 15

Slide 15 text

don’t be afraid to start the hardcore continuous integration

Slide 16

Slide 16 text

Testing

Slide 17

Slide 17 text

Mocha + Chai framework: Node and Browser support Separated assert libraries Tons of reporters mocking: SinonJS Spies, Stubs, Mocks Assertions for invocations wide framework support Faking AJAX, server module dependency mocking: SquireJS Dependency injector for RequireJS mock / store Unit testing

Slide 18

Slide 18 text

Unit testing is a must in every architecture but it’s not enough for client side code!

Slide 19

Slide 19 text

Testing real browser functionality with mocking and simulating the DOM can be a pain in the …

Slide 20

Slide 20 text

Node.js based navigation scripting PhantomJS / SlimerJS support screenshot capture you can skip or use your own testing framework Solution: CasperJS

Slide 21

Slide 21 text

Right now we have: parallel execution thanks to an own grunt task solution Tools based on Casper: Screenshot comparisan tool, regression testing (PhantomCSS) own testing wrapper layer with different presets and transparent modules. User.login(), etc. It’s really flexible and easy to customize!

Slide 22

Slide 22 text

Automation

Slide 23

Slide 23 text

Manual processes simply won’t work… but there is an easy cure!

Slide 24

Slide 24 text

GRUNT || GULP we use Grunt! Why not gulp? Bad question, both are awesome, move on, and pick one!:)

Slide 25

Slide 25 text

we could migrate our old PHP / Ruby / etc. based frontend jobs to Node there is a transparent layer for every frontend related task thanks to our dynamic GruntFile.js solution, adding new tasks is fast Thanks to Grunt

Slide 26

Slide 26 text

CI integration is important! with an automation layer, it’s easy to do

Slide 27

Slide 27 text

Rules & standards insurance for the future

Slide 28

Slide 28 text

Follow your rules, because if you break them, they are not rules anymore…

Slide 29

Slide 29 text

Code style!

Slide 30

Slide 30 text

JSHint ! ! pros: .jshintrc huge community wide IDE / Text editor integration grunt / gulp plugins ! cons: still regexp based (JSLint fork) not pluginable nearly impossible to write semantic rules

Slide 31

Slide 31 text

ESLint ! pros: pluginable tons of new rules rapidly growing community semantics ESPRIMA growing IDE / Text editor integration ! cons: you can tell maybe!

Slide 32

Slide 32 text

We’ve created our own rules

Slide 33

Slide 33 text

Complexity? Lines of code (LOC) Halstead indexes Maintainability index Cyclomatic complexity linearly independent paths in the method

Slide 34

Slide 34 text

JSComplexity & Plato We run complexity report in Jenkins nightly build for our whole JS codebase https://www.npmjs.org/package/complexity-report Plato is a great tool for manual examinations https://github.com/es-analysis/plato

Slide 35

Slide 35 text

Use your CI or Git hooks to force your rules & standards

Slide 36

Slide 36 text

Modules, modules!

Slide 37

Slide 37 text

async module loading dependency injection project based SOA workflow, we have to avoid code duplication in several repos/projects Why we’ve started our modularisation marathon

Slide 38

Slide 38 text

Do not worry! Code modifications can be automated! http://esprima.org/ { "type": "Program", "body": [ { "type": "VariableDeclaration", "declarations": [ { "type": "VariableDeclarator", "id": { "type": "Identifier", "name": "city" }, "init": { "type": "Literal", "value": "istanbul", "raw": "'istanbul'" } } ], "kind": "var" }, { "type": "IfStatement", "test": { "type": "BinaryExpression", "operator": "===", "left": { "type": "Identifier", "name": "city" }, "right": { "type": "Literal", "value": "istanbul", "raw": "'istanbul'" } }, "consequent": { var city = ‘istanbul’; ! if (city === ‘istanbul’) { conf = 'jsist'; }

Slide 39

Slide 39 text

NPM modules? Maybe private ones? more!

Slide 40

Slide 40 text

private repo server: Sinopia internal GitLab repos for each package grunt release task for NPM module release NPM in private https://github.com/geddski/grunt-release https://github.com/boennemann/grunt-semantic-release

Slide 41

Slide 41 text

Why? we can manage our dependencies in different projects / services separated tests & documentation for each module we also use NPM for non-node package management Yeoman for automated project configuration

Slide 42

Slide 42 text

That’s not dark anymore!:) This is where we are right now!

Slide 43

Slide 43 text

What we’ve achieved so far 600+ modules created hundreds of unit tests and Casper tests, and growing rapidly new and important core features are moved to the new structure we started to create our private NPM modules like hell! ready for Async module loading

Slide 44

Slide 44 text

Remember: It’s never too late! @matenadasdi