Ustream vs Legacy, It's never too late to start your fight! #Jsist 2014

Preview:

DESCRIPTION

A general talk about Ustream's revolution on our aging codebase. We had to make critical changes on our codebase to achieve more stability and scalability on the client side. This talk is about encouragement with lot of tips and tricks if you are in a similar legacy situation. https://speakerdeck.com/matenadasdi/ustream-vs-legacy-its-never-too-late-to-start-your-fight-jsist-2014

Citation preview

Ustream vs Legacy

@matenadasdi

Ustream basics

80.000.000 visitors / month

5.000.000+ viewer hours on tough days

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

Everyone starts in the dark…

but there is always light in the end of the tunnel

Our goal was to achieve

more stability and scalability

in our frontend codebase

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”

It’s a new ERAit’s a heaven of tools and new solutions

for frontend developers nowadays

we had 5 stages in our long journey

it may help or inspire you too

Structure

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…

not the framework, the way of thinking matters

always think in layers with separated responsibilities

Sync Socket (full-duplex)Async

get data set data

DOM

AJAX WebStorage Cookies Socket Ustream Flash APILongpoll Embeds

Views

manipulates events

Controllers

control notify

Logics Models

get data set data

our new small framework is under 10kb

but we had millions of lines written in an old style

don’t be afraid to start the hardcore continuous integration

Testing

Mocha + Chaiframework:

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

Unit testing is a must in every architecture

but it’s not enough for client side code!

Testing real browser functionality with mocking

and simulating the DOM can be a pain in the …

Node.js based navigation scripting

PhantomJS / SlimerJS support

screenshot capture

you can skip or use your own testing framework

Solution: CasperJS

Right now we have:

parallel execution thanks to an own grunt task solution

Tools based on Casper: Screenshot comparison 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!

Automation

Manual processes simply won’t work…

but there is an easy cure!

GRUNT ||  GULP

we use Grunt!

Why not gulp?

Bad question, both are awesome, move on, and pick one!:)

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

CI integration is important!

with an automation layer, it’s easy to do

Rules & standards insurance for the future

Follow your rules, because if you break them,

they are not rules anymore…

Code style!

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

ESLint

!

pros:

pluginable

tons of new rules

rapidly growing community

semantics

ESPRIMA

growing IDE / Text editor integration

!

cons:

you can tell maybe!

We’ve created our own rules

Complexity?

Lines of code (LOC)

Halstead indexes

Maintainability index

Cyclomatic complexitylinearly independent paths in the method

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

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

Modules, modules!

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

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": { "type": "BlockStatement",

var city = ‘istanbul’; !if (city === ‘istanbul’) { conf = 'jsist'; }

NPM modules? Maybe private ones?

more!

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

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

That’s not dark anymore!:)

This is where we are right now!

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

Remember: It’s never too late!

@matenadasdi

Recommended