Post on 14-Jun-2015
description
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