[WG Proposal] GitLab Modular Monolith for FE
Proposal
Let’s create a working group focused on applying the GitLab Modular Monolith architecture for Frontend.
Justification
Here's some problems we regularly run into in Frontend:
- As a Contributor, it’s hard to find what can be reused across features.
- As a Contributor, it’s hard to know where new things should live and if there’s possibly preexisting code that does the same thing (i.e. at one point we had 3+ different project dropdowns).
- Often modules are reused across features because they happen to provide a subset of common features. This creates extra coupling to the unused parts of the component.
- Often modules are tweaked to support reusability outside their original scope. This creates leaky and fragile abstractions.
Analysis
There’s a missing level of encapsulation which leads to low cohesion and tight coupling across FE files. This missing level is package encapsulation. Right now, all of GitLab FE is treated as one package and there are no clear boundaries between files in GitLab FE. Any FE file can import any other FE file.
Modular Monolith:
From the- Even though we strive for having an approachable open-core architecture we need to strengthen the boundaries between domains to retain velocity and increase development predictability.
- It is difficult for engineers to build a mental map of the application due to its size. Even apparently isolated changes can have far-reaching repercussions on other parts of the monolith.
Goals/Ideas:
- Architecture Blueprint: We should create a GitLab Modular Monolith for FE architecture blueprint, similar to this one. Based on this comment we might want to start by just ammending the existing architecture blueprint by calling out the FE approach.
- Documentation and Searchability: We should document the reusable parts of the GitLab monolith so that it's clear what can safely be reused and where new reusable modules should live.
-
Package Encapsulation: Without going full monorepo, how can we enforce package-level cohesion and encapsulation? It should be clear what the responsibility of the top-level folders are and we should cyclical dependencies across the top-level folders.
-
vue_shared
is an example of a low-cohesion package that contains some generally reusable utility components, but also contains some very domain-specific components. There are also some modules invue_shared
that reach out to domain specific top-level folders and these folders reach back tovue_shared
creating a package-level cyclical dependency.
-
Brainstorm
- Package Encapsulation:
- We don’t need a monorepo, but can use eslint to treat top-level folders in
app/assets/javascripts
as “packages”. - Top-level folders have to declare what other top-level folders they can import from.
- Differentiate between
apps
andlibs
.apps
can’t be imported by any other top-level folder. - Open questions:
- What about the
pages/
? - Should we support nested top-level folders? Example:
lib/utils/project
orlib_project_utils
?
- What about the
- We don’t need a monorepo, but can use eslint to treat top-level folders in
- Documentation and searchability:
- Let’s mark what’s actually meant to be reusable across the app.
- Let’s compile the metadata of the reusable modules into a helpful documentation similar to lodash’s documentation. The source for this can just be a jsdoc of a block that’s marked
@gl-util
or something like that.
Exit criteria for WG
This WG is all about tooling for enforcing modular encapsulation in the FE. Major refactoring of the existing code is outside the scope of this WG.
- Architecture Blueprint: The WG should document long-term Frontend concerns for the GitLab Modular Monolith effort and an iteration plan how we'll get there. This will likely manifest as updates to the GitLab Modular Monolith.
- Documentation: The WG should provide tooling and a process for documenting commonly reusable modules within the main GitLab project. This documentation should be easily searchable such that new contributors should be able to find if a reusable functionality already exists or not.
- Encapsulation tooling: The WG should provide tooling an a process for enforcing package-level cohesion and encapsulation. This will enable the rest of the company to create enforceable domain-specific boundaries within the monolith.
Map out the Working Group
Working Group Directly Responsible Individual | @pslaughter |
Executive Sponsor | TBD |
Functional Lead | TBD |
Frequency of meetings | Weekly |
Inclusivity of team members across the globe | In this issue we did a split sync meetings which worked out well. |
Frequency of status updates for use in status tracker | Bi-weekly |
Designating DRI for overall project management, including scheduling meetings and tracking project status | TBD |
Create a Slack channel for collaboration. The Slack channel name should start with the #wg_ prefix. | TBD |
Activities of WG | Members of the WG will engage in documentation, iteration planning, and tool evaluation/development. |