Developing large apps is difficult. Ensuring that code is consistent, well structured, tested, maintainable and has an architecture that encourages enhancement is essential. When it comes to large server-focused apps, solutions to this problem have been tried and tested.
But, how do you achieve this when building HTML5 single page apps?
In this talk we’ll cover the signs to watch out for as your HTML5 SPA grows and provide examples of some of the tooling types that can contribute-to as well as ease the growing pains. Finally, we’ll demonstrate how tooling can be used to support a set of conventions, practices and principles that enable a productive developer workflow where the first line of code is feature code, features can be developed in isolation, code conflicts are avoided by grouping assets by feature and features are composed into apps.
The demonstrations will use BladeRunnerJS, an open source developer toolkit written in Java, but the concepts are widely applicable.
5. @leggetter#HTML5AtScale
–Addy Osmani, Patterns For Large-Scale JavaScript Application
Architecture
In my view, large-scale JavaScript apps are non-
trivial applications requiring significant developer
effort to maintain, where most heavy lifting of data
manipulation and display falls to the browser.
7. @leggetter#HTML5AtScale
Caplin Trader
• SDK:
• ~1,000 JavaScript files
• ~131,000 LoC
• ~131 lines per file
• ~650 test files
• ~95,000 test LoC
• Typical Apps:
• ~425 JavaScript files
• ~50,000 LoC
• ~117 lines per file
• ~200 test files
• ~21,000 test LoC
11. @leggetter#HTML5AtScale
Gmail & Caplin Trader
• Large Single Page Apps (SPAs)
• Complex functionality
• Complex interactions
• User
• Technology
• Leave open all day
31. @leggetter#HTML5AtScale
What is a service?
• Use services to access shared resources
• In-app inter-component messaging
• Persistence Service
• RESTful Service
• Realtime Service
• Services are a Contract/Protocol/Interface
32. Setting & Getting Services
• Use a unique identifier for each service i.e. a simple string
• Register (code or config). Code example:
!
• Get
http://martinfowler.com/articles/injection.html#ADynamicServiceLocator
33.
34.
35.
36. @leggetter#HTML5AtScale
Why use services?
• Features should not directly communicate
• Easily change implementation
• Implementations can be injected for different scenarios:
• Workbench / Test / App
44. @leggetter#HTML5AtScale
AT Process
3
3. Launch browser + App
1
1. Pair Browser + Backend VM
2
2. Reset & restart backend services
5
5. Record results
4
4. Execute ATs
6
6. Reset backend services
8. Execute next test…
8
7
7. Restart/refresh browser
45. @leggetter#HTML5AtScale
Test Results
• ~1300 UTs
• ~500 ATs
• 50 VM infrastructure to run tests concurrently
• 8 Hours
• Test results highly unreliable
• We could only run a full suite of tests once per day - at
night
46. @leggetter#HTML5AtScale
Inefficient Testing!
• Resetting back end services is too slow
• Lots of moving parts. Things can go wrong.
• Services don’t start = app won’t work. Not code but
environment failure.
• We want to avoid IO
• … and querying the DOM
50. End-to-End Module Testing
• Testing features in
isolation
• Change view model
and assert against
mocked Service
• Inject fake service,
make calls and assert
View Model
51.
52. Need Proof?
Our full suite Caplin Trader
testing time went from
>8 Hours
< 30 minutes
Much less for a single feature