Initial SOW Notes
Initial Statement of Work Notes (actual document is elsewhere)
We want to begin by doing some additional discovery on Piral and how it might fit into Open edX. We expect this discovery to answer a few questions (with reasonable certainty) before we dive into coding up a reference implementation.
Overall Deliverables
Documentation on the wiki of all the discovery details as described below.
A frontend working group presentation summarizing the those findings.
Overall Estimate
88 to 128 hours, details below.
Frontend Shell Application
SOW Description
Should frontend-app-shell (available at https://github.com/openedx/frontend-app-shell )- or a new pilet hosted therein - reimplement the services frontend-platform (available at https://github.com/openedx/frontend-platform ) currently provides, thus deprecating the latter? Alternatively, should frontend-platform be extended to work under both regimens (Piral and standalone)?
Outline an implementation strategy, corresponding to which option is recommended.
Earlier discovery resulted in frontend-app-shell, which is the Piral “shell” wrapper around individual micro-frontends (which are “pilets” in Piral parlance - i.e., routes or parts of the page). The repository today is trying to fulfill several roles:
At runtime, it’s trying to wrap the services and libraries available in frontend-platform so they can be shared between MFEs as part of the shell application.
It’s intended to expose the above services/libraries to MFEs, meaning it acts as a dependency of MFEs.
It acts as a Piral development server if started directly, but also as a build-time library for MFEs so that a development server can be launched from an MFE without checking out frontend-app-shell itself.
It’s the actual application shell which will route between MFEs, contain the header/footer, and be the outermost wrapper to all our MFE pilets.
It’s not clear that these four roles should all be in the same repository, or be split up in some way. This particular arrangement (wrapping frontend-platform) also means that MFEs would need to be updated to import frontend-platform’s exports from frontend-app-shell, rather than from frontend-platform as they do today. This will be a heavy lift.
Discovery:
Can we take advantage of new build targets in frontend-build (which is already an MFE dependency) for development servers.
Possibly folding frontend-app-shell into frontend-platform to reduce the impact on MFEs.
How frontend-platform could be modified in place to be both backwards compatible and support Piral’s shell application.
Deliverables:
Diagramming/documenting the intended relationships here and how it should all work together.
Effort:
24 - 32 hours (3 - 4 days)
About a day of work investigating each of the “roles” above, with the goal of coming up with a sane written/diagrammed plan for how we should proceed.
Shared Dependencies
SOW Description
Beyond React and Paragon, what other libraries should be provided by frontend-app-shell and expected as peer dependencies by the MFE pilets?
These would be, in effect, mandates to use not only particular libraries, but particular versions of these libraries; MFEs that circumvent them would be accruing tech-debt. Part of the deliverable here is a recommendation on when to introduce this type of dependency, and when not to.
One of the big wins with an MFE framework like Piral is that we’ll be able to share libraries between MFEs. We want to come up with a list of what libraries should be shared (and peer dependencies in MFEs). These libraries will likely become dependencies of frontend-app-shell or frontend-platform depending on the previous question.
Discovery:
Which libraries should be shared?
What are the guidelines on when to add things to the shared dependencies?
Are there any gotchas / complexities in how Piral shares libraries between pilets? Does it support allowing pilets to request divergent versions?
Deliverables:
List of libraries we want to start with.
Rule of thumb guidelines which may be codified later into an OEP or ADR.
Understanding of how piral manages shared libraries and if there’s any flexibility in its approach.
Effort:
8 - 16 hours (1 - 2 days)
One day to audit MFEs for likely shared dependencies
One day for investigating Piral’s capabilities here.
Central Data Store
SOW Description
Should the shell provide a central data store to be used by the MFE pilets, or should the latter be free to manage state independently?
If so, what would be the recommended mechanism? Redux?
If not, what would be the recommended way for pilets to communicate state to/from the shell?
Many MFEs use redux for global state management, and could likely share some common information, particularly pertaining to the logged in user and their account.
Discovery:
Should the Piral shell supply a shared data store, such as redux?
Can redux function with multiple stores on the page at the same time?
What facilities for intra-pilet communication, and pilet-shell communication, exist in Piral?
Do we need to add an eventing system? Are there use cases for this?
Deliverables:
A written proposal for shared data and eventing, taking into account the above.
POC of the approach. (Maybe timebox this)
Effort:
24 - 32 hours (3 - 4 days)
One day for POC of multiple redux stores to see if that’s even an option (i.e., let the MFEs do whatever they want)
One to two days for understanding what Piral gives us for communication and how we could use it.
One day to write up the proposal (some folks feel redux is controversial… that said, we’re already fairly committed to it)
Bundle Splitting
Practically speaking, if we were to split frontend-app-learning in pieces so they could be loaded independently, what would that look like? Do we want to do frontend-app-learner-dashboard instead? What are the best practices around lazy loading/bundle splitting?
Discovery:
Understand how piral suggests doing lazy loading - is it any different than React’s existing facilities for it?
Decide what the right size is for a split bundle, or does it even matter? Should folks just reach for this tool regularly?
Deliverables:
Description/example code for how a split could be done.
Written out guidelines on when bundle splitting is a technique we should take advantage of.
Effort:
8 - 16 hours (1 - 2 days)
One to two days to understand how we would implement the split / consume it with Piral, and to write that up.
Performance
How does Piral change the time it takes to build MFEs (both collectively and individually)? How does Piral impact core web vitals of the runtime application?
Discovery:
Construct two sample applications as both MFEs and pilets, and benchmark the build times and core web vitals of them under the two architectures. Doing this without using an actual MFE should make it a fairly quick exercise, but help us understand how the performance profiles differ. We can make the applications a similar code size to our existing MFEs by adding dependencies, some lorem-ipsum style application code, and a few asynchronous sleep-style calls to emulate ‘data loading’.
If the numbers from this are promising, we can also use this as marketing/an explainer for why we’re doing this Piral work.
I have a powerful laptop - we may want to test on something lower powered too.
We should also consider mobile web performance and impact generally in this exercise.
Deliverables:
The experiment code.
The actual benchmark numbers.
Effort:
16 - 24 hours (2-3 days)
One day to understand the page load (core web vitals) profile of Piral with bundles of roughly our size, testing with a Profiler (Chrome developer tools)
One to two days to construct an experiment that compares Piral-based build times with MFE-style build times with the same set of dependencies and libraries, attempting to take advantage of Piral’s composability and shared dependency capabilities.
Other Concerns
What other changes to frontend-app-shell and the MFEs do we foresee having to make in the process of creating a reference implementation? This is a complex project and there are devils in the details, and the current POC isn’t directionally aligned with some of the above, or hasn’t investigated it. For now, it’s probably enough to spend a little time becoming familiar with the POC so we’re not surprised later.
Discovery:
Review the POC work in detail.
Deliverables:
A list of any key risks found in the above review.
Effort:
8 hours (1 day) to review the work and write up findings.