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 and test, 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.
We think these problems are rooted in or molded by MobileFrontend's component framework. This framework is unique to MobileFrontend and has larger overarching concerns:
- **Monolithic and integrated.** The component framework parts of MobileFrontend are not distinct from the rest of the codebase. For example, it is not possible to "npm install" MobileFrontend's custom framework and reuse it another application. Because it is nonredistributable, this limits usage of the framework to MobileFrontend.
- **Informal API and versioning.** Although the lack of any external users for a framework improves its malleability, the informality afforded hides significant changes that would normally be well-planned, scoped, and semantically versioned. I.e., changes regardless of their significance are often made organically with decisioning made implicitly by the needs of the moment, and as a spot fix, rather than explicitly architected and as a codebase-wide revision. For instance, an API breaking change could be made with the same gravitas and consideration as fixing a typo. Additionally, the lack of a formal and well-defined public API hinders readability, clouds responsibilities, and obscures the goals of the framework.
- **Single-purpose and non-reusable.** MobileFrontend's framework is built to solve the problems at hand. It is not generic. This means that not only is it likely too specific to be used for anything but exactly what it was built for (and therefore only useful to MobileFrontend), but also that many use cases have likely been unconsidered. The framework may require an architectural overhaul unexpectedly at any time during normal feature development, which is a serious liability to product roadmaps.
- **//Terra incognita.//** Unique tooling produces unique problems hitherto unseen. When functionality breaks or a new feature is needed, it's a first. There's no prior art, similar references have to be viewed through a distorted lens, and a brand new approach is required for this one-of-a-kind circumstance. The premise for many changes in MobileFrontend is uncharted territory which is extremely inefficient.
- **Limited expertise.** There is little documentation, demonstration of idiomatic patterns, or domain experts except what Readers Web itself cultivates for MobileFrontend's tailor-made framework. It is a high cost to build and maintain these from within and the learning curve for new hires is steep and daunting even when the materials exist and are up to date. When an author leaves, they take a portion of this expertise with them. When the majority of a team departs, as is the case for Readers Web, a library of knowledge is lost. Because MobileFrontend's framework is nonredistributable, there are no professional teachers, books, videos, or universe of open-source examples to rely on.