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 technical, social, and product 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.- **Limited vision.** There is a singular user of MobileFrontend's framework: Readers Web. No one cares about even fundamental issues because no one else is using it. Issues are quite likely “unknown unknowns” in one of our blind spots. Whereas, when a well-known open-source framework makes a mistake, there are reports (even complaints), and discussions until it is resolved (“given enough eyeballs, all bugs are shallow”). MobileFrontend's homemade framework does not have a culture of development, it's growth is limited, and it's doomed to be understood and used by few and forever bounded by the abilities of a few authors.
- **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 a universe of open-source examples to rely on.
- **Effectively closed source software.** For many reasons, a nearly unsurpassable barrier to participation exists in MobileFrontend's custom framework to those outside its authorship. This approach to development is non-inclusive, does not welcome a diverse community of contributors—not only in terms of numbers, but in terms of background—and discourages the usual benefits and freedoms associated with free and open-source software. The MobileFrontend codebase, which contains the framework for one of the world's most popular websites, has only been [[ https://github.com/wikimedia/mediawiki-extensions-MobileFrontend | starred by 43 people and forked 16 times in the past eight years ]], which is orders of magnitude less than standard FOSS alternatives. By the de facto metrics of success in the open-source community, MobileFrontend's framework has not lived up to [[ https://meta.wikimedia.org/wiki/Mission | the mission ]] or [[ https://www.mediawiki.org/wiki/Wikimedia_Engineering_Architecture_Principles | Wikimedia engineering architecture principles ]]. In other words, MobileFrontend's framework limits our community to a small closed set of mostly employees instead of exploring the globally diverse population our movement strives to reach and connect with. We believe products should be built by everyone for everyone so that no group's needs are excluded. Practically speaking, it is becoming increasingly harder to find contributors, even paid contributors, that //can// make changes to MobileFrontend, and it will only get harder as MobileFrontend's framework lags further behind.
- **Noncompetitive.** MobileFrontend's anonymous framework, due to its unpopularity, isolation, limited resourcing, and closed source-like nature, cannot compete with open-source alternatives. It has never been and will never be competitive. Readers Web does not have the resources to build a competitive framework or even a framework to fulfill its current needs—nor should it strive to.
- **No escape hatch.** Migration guides are only written for projects that are popular and usable elsewhere. MobileFrontend's framework is neither because it's single-purposed and nonredistributable. Readers Web will sooner or later have to unravel all code written using the existing framework, and how that code transitions to a new framework. This problem will worsen as more code is built using the custom framework.
- **Custom tooling is incompatible with other open-source software.** Many tools are built for popular open-source frameworks, often with out-of-the-box support for integration. MobileFrontend's bespoke framework by default loses access to this entire ecosystem of tooling and any additional tooling needed must is roll-your-own or do without.