Frontend JavaScript Architecture - simpler (on hold) 🇵🇱 🇬🇧 2 days
Why this course?
Modern frontend JS development is way more complicated than
it needs to be.
Frameworks
Current mainstream: bloated frameworks rewriting most of the browser features,
with code complexity impenetrable for non-core contributors, enormous bundle sizes and
never ending spiral of load time performance tricks
What could we do instead: composable zero dependency micro-libraries that we can fully understand at a code level without being a core contributor
Testability
Current mainstream: questionable testing practices (monkey patching and overwriting imports)
What could we do instead: 100% pure and testable code in the user space
Language features
Current mainstream: overuse of JS language features and tools
My JS "the best parts": pure functions and object literals
Things I'd like to avoid when writing business application code: this, new, classes,
prototypes, promises, async/await, callbacks, generators,
observables, mutations, reassignments, loops, hooks, nonstandard language
extensions requiring transpilers/bundlers
Architectural patterns
Current mainstream: architectural patterns from the OO world that require lots of discipline, effort, boilerplate and elaborate explanation (repositories, gateways, SOLID, dependency injection, ports and adapters by convention etc.)
What could we do instead: functional architecture, dependency rejection with effects as data, ports and adapters by default
Training method
The main theme of this training is "fits in my head" - how to create JS applications that we can reason about.
Instead of using code generators and casting magic spells from the CLI we learn things from first principles.
Understanding every single line of code that we add. Solving one little problem a time.
Agenda
Frontend architecture evolution
- DOM spaghetti
- Model-View-Presenter (MVP)
- Model-View-ViewModel (MVVM)
- Elm Architecture
Development without build tools
- Native ES6 modules support in modern browsers
- Tagged-templates as an alternative to JSX
- Running npm dependencies in the browser without webpack (snowpack)
- Build as a production optimisation step for older browsers support and for load time performance
Functional architecture
- View as a function of state
- Centralized immutable state
- One-way data flow
- Business logic as state transitions
- Effects as data
- Moving all impure code ouf of the user space
Pure IO without promises/async/await/observables
- Effects and subscriptions (long-running effects)
- HTTP effect
- localStorage effect
- Random effect
- WebSockets subscription
- Server-Sent Events subscription
- Dependency rejection over Dependency injection
Clean Code
- Removing duplication and assigning responsibilities in a growing system
- Refactoring view functions
- Refactoring business logic
- Separating library code from business application
- Making impossible states impossible
Runtime performance optimisation
- Handling large DOM trees
- Analyzing runtime performance flame charts in DevTools
- Memoization
- Keyed lists
Unit Tand Integration esting
- Unit testing business logic
- Unit testing effects (I/O) without mocks/stubs
- Integration tests with jsdom
- Testing async code with automatic waiting
Browser Testing
- E2E testing in the browser with cypress
- Abstracting away async code with automatic waiting
- Time travelling in tests
- Debugging failing tests with snapshots and DevTools
- Speeding up repetitive operations across tests (e.g. login)
- Stubbing API calls for less flaky tests and easier setup
Deployment to production
- Bundling and transpilation with esbuild
- Static hosting and Continuous Deployment to Netlify
Tooling
- hyperapp - minimalist, simple, functional web framework in < 2kB
- hyperlit - view templates with optional transpilation in < 1kB
- mocha - testing without magic
- prettier - consistent code formatting
- snowpack - npm modules in the browser
- http-server - static file serving
- esbuild - faster bundler
- netlify - static files deployment platform