NOTE: this task is a **draft** and should be considered **work in progress** until resolution or this notice is removed.
The purpose of this task is to assess and aggregate common difficulties we have encountered when building and maintaining components in MobileFrontend.
This task is **not** for solutioning.
=Draft
The following component design patterns are recurring and have worked poorly in MobileFrontend:
- **Mixed responsibilities.** Considerable boilerplate is necessary to build and compose components. This has led numerous modules to own too many concerns which diminishes readability and limits composability, reusability, and testability.
- **Manual DOM reconciliation.** Frequently, JavaScript is used to progressively enhance a webpage originally modeled and rendered on the server. The client JavaScript must manually parse and manipulate the server’s data then update the DOM with the new state. Not only is this code very tricky to write correctly, confusing to read, and costly to maintain, it’s exceptionally fragile: changes to the server, the client, or dependent APIs each have the potential to cause unbreak now bugs.
- **Lengthy inheritance hierarchies.** Long class chains are difficult to reason about, compose, and test. Even small changes often require thorough knowledge of all ancestors and descendants, and the problem is exacerbated by JavaScript’s untyped nature and the sprawling MediaWiki ecosystem.
- **Heavyweight.** View is the superclass for every component in MobileFrontend. This single level of inheritance implies complicated lifecycles, jQuery, event buses, a class hierarchy that includes at least 500 lines of code, and other historical baggage that would be unnecessary for many use cases but is currently the responsibility of every component.
- **Do-it-all constructors.** Construction of a component that assumes dependencies instead of asking for them hinders composability and testability. For Views, the superclass of all components in MobileFrontend, construction of a subclass implies template rendering, full DOM inflation, and other set up.
- **No standard component patterns.** There are many inconsistencies in how components are structured and composed. Many of the patterns that do exist in MobileFrontend are equally considered antipatterns. Each new feature built is something of a pioneer in trying to break free of the inadequacies faced in designing previous features but ultimately only adds another unsatisfying way of doing things to the mounting technical debt. Instead of building “just another feature,” feature development often feels like the first time and costs like it too. MobileFrontend has no paragon for composable components.
- **Imperative UI.** MobileFrontend relies heavily on jQuery for the creation of components. Its usage has encouraged building features in a way that is both verbose and challenging to reason about, and discourages composition. In some cases, the results have been nearly incoherent. Additionally, the outputs of the API often return more API-specific types that imply further usage such that any interaction compounds.
- **Informal application state management.** MobileFrontend’s state management is ad libbed and a rich source of bugs. DOM state, singletons, other global states, several event buses, promises, and callbacks are all used to communicate and derive the current state.
- **Implicit dependencies.** Many files in MobileFrontend rely on implicit dependencies during execution. These frequently add side-effects to imports / requires which breaks tree-shaking, makes subjects difficult to test, inhibits prototyping, and impedes external code reuse by third-parties.
- **Haphazard route management.** Endpoints are declared impromptu in different places such that it would be difficult to list all of the endpoints provided by MobileFrontend. This has created problems in managing browser history and UI state, providing a stable API to users, and developer conceptualization.