Skip to content

Commit 9065b37

Browse files
committed
squash!: Update ADR to reflech WIP openedx#440
1 parent ce9494e commit 9065b37

File tree

1 file changed

+39
-83
lines changed

1 file changed

+39
-83
lines changed

docs/decisions/0007-compile-common-theme-for-all-mfes.rst

Lines changed: 39 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -29,51 +29,54 @@ SCSS.
2929
This effectively means that all MFEs share a large chunk of common styling code
3030
with a comparatively much smaller set of styles applied over that.
3131

32-
There is scope here to properly split the MFE stylesheet into multiple parts,
33-
one being the common code as represented by the above imports, and another for
34-
MFE-specific code, and build them separately.
32+
With the introduction of a new styling mechanism in the `design tokens ADR`_ it
33+
will be possible to build a Paragon theme that contains a majority of CSS code
34+
that is independent of branding variables, which are loaded from a separate
35+
variables CSS file.
3536

36-
One thing that prevents this is that MFEs need these SCSS imports to get
37-
variables. In a number of cases these can be replaced with either
38-
Paragon/Bootstrap classes, or CSS variables. A separate ADR in `Paragon
39-
<https://github.com/openedx/paragon/pull/1388>`_ covers the situations where
40-
this isn't possible yet.
37+
With that change we can now compile a common cross-MFE Paragon CSS that can be
38+
loaded from a common source for all MFEs, and a separate CSS containng all the
39+
theming variables. There can also be multiple variable definitions for different
40+
themes that correspond to a dark and light theme or potentially other variants.
4141

4242
Decision
4343
********
4444

45-
Common cores styling that is to be applied to all MFEs should be part of a
46-
separate stylesheet and built separately from the MFE-specific stylesheet.
45+
Paragon CSS code can be compiled once and loaded in all MFEs from a URL provided
46+
by an environment variable or via runtime configuration. The runtime
47+
configuration will allow having a single deployment of an MFE cater to multiple
48+
sites by varying the theme loaded for each site.
4749

48-
Both these stylesheets will be included in each MFE, however the common
49-
stylesheet can be loaded from a common source for all MFEs. This will allow for
50-
deploying the common theme stylesheet without redeploying MFEs.
50+
The CSS code will be split into two parts, the first is the core stylesheet that
51+
contains foundational code such as layout, typography etc. One or more
52+
additional stylesheets will need to be provided which will include the CSS
53+
variables that define the colours, spacing, font faces, sizes etc.
5154

52-
The mechanism for loading this common stylesheet will need to be different from
53-
the mechanism for loading the MFE stylesheet. A JavaScript theme loader will
54-
contain the location of the SCSS file and will add this stylesheet to the
55-
document.
55+
There is scope for provding multiple stylesheets that contain variable
56+
definitions. These can correspond to a standard light theme, a dark theme and
57+
potentially other themes.
5658

57-
The common theme package will be similar to the branding package, but can be
58-
deployed independently of MFEs. It will produce a CSS stylesheet, and a
59-
JavaScript loader that will load this stylesheet. When deploying MFEs, they can
60-
be provided a configuration variable that contains the location where this
61-
theme loader is deployed.
59+
In order to enable this mechanism there will be changes to the frontned platform
60+
that include a mechanism for checking if a common theme location is defined,
61+
whether via an environment variable or in runtime configuration. If so, code in
62+
the AppProvider function that is used by all MFEs will load the theme from here
63+
automatically.
6264

63-
The frontend-platform repo can host code that simplifies using themes. It can
64-
check if a theme loader is configured, and if so, dynamically load the theme
65-
from there. Otherwise, it can continue using the existing mechanism of building
66-
and deploying the theme for each MFE for backwards-compatibility. It can also
67-
provide hooks for loading the theme and potentially/eventually also selecting
68-
a theme.
65+
There will also be an API for runtime loading of a theme, which can allow MFEs
66+
to provide a UI for runtime theme switching.
6967

7068
Consequences
7169
************
7270

73-
With a single common stylesheet for all MFE, they should load quicker since the
74-
stylesheet can be cached once for all MFEs. It also makes theme rebuilds much
75-
quicker, and eliminates the need for rebuilding each MFE for minor change to
76-
the theme.
71+
Since these stylesheets are shared across all MFEs, it can be uploaded to a CDN,
72+
speeding up loading of all MFEs since a cached stylesheet will be loaded for all
73+
MFEs once a user has used any MFE. Likewise any updates pushed to the CDN can
74+
automatically be pushed to all MFEs through runtime configuration without
75+
needing to rebuild all of them. Changes to theming variables can also
76+
automatically reflect across all MFEs since they load from a shared location.
77+
78+
This will also make theme rebuilds much quicker, and eliminate the need for
79+
rebuilding each MFE for minor change to the theme.
7780

7881
For context, on a sample development machine, rebuilding an MFE takes roughly
7982
one minute, of this, on the same machine, around 3-4 seconds is the time it
@@ -82,58 +85,11 @@ takes to build the theme.
8285
By continuing to support the existing theming mechanism, the current mechanism
8386
for theming can continue working for those who need it.
8487

85-
Since there is a JavaScript-based loader involved, there is potential for
86-
flashing of unstyled content during loading, however this can be avoided by
87-
making the theme loader part of the init process so it runs before the app is
88-
considered ready.
89-
90-
Another major consequence of this change would be that the CSS code for Paragon
91-
would be loaded using a different mechanism than the JavaScript code of Paragon.
92-
The CSS code would be compiled into the theme whereas the JS code will be loaded
93-
directly. This means that if different versions of Paragon are used for an MFE
94-
vs the common theme, then there is a chance that an incompatible version of the
95-
CSS could be loaded for the MFE. This will make it all the more important to
96-
ensure that version of Paragon used across all MFEs is compatible. This will be
97-
simpler for named releases than for those running latest code changes.
98-
99-
Rejected Alternatives
100-
*********************
101-
102-
- **Loading the common CSS directly instead of with a JavaScript based loader**
103-
104-
This ADR proposes using an intermediary JavaScript loader to load CSS rather
105-
then just having the configuration variable point to the stylesheet itself.
106-
This is done for performance reasons.
107-
108-
Currently, when an MFE is built, each static asset contains the hash of the
109-
asset in the file name. The ``index.html`` file includes these generated file
110-
names, and if any asset changes the ``index.html`` file is updated.
111-
112-
When a user reloads an MFE page the index page is reloaded, and if any assets
113-
have changed, their file names will have as well and they will be loaded
114-
fresh. Unchanged assets will keep using the same name and can load from the
115-
cache for a very long time.
116-
117-
If the file names don't change with the content, then there is a risk of
118-
loading older code from the cache, or (if caching is disabled) of loading a
119-
huge chunk of code with each refresh and having a huge hit on performance.
120-
121-
So to maximise the amount of time for which stylesheets are cached, and
122-
minimise the amount of code that needs to be loaded on each refresh, we need
123-
to have a light intermediary loader that provides the location of the
124-
stylesheet. The bulk of the CSS can then be cached for as long as it is
125-
unchanged.
126-
127-
- **Have the theme loading code in each MFE**
128-
129-
This doesn't change much about the rest of the mechanism of this ADR, but it
130-
causes a lot of code duplication across MFEs. Just like ``frontend-platform``
131-
handles authentication for all MFEs, it can also handle dealing with the theme
132-
loader.
133-
88+
A theme switching UI can also potentially be made part of the header or footer
89+
component to make it available across all MFEs easily.
13490

13591
References
13692
**********
13793

138-
- `ADR to introduce CSS variables to parargon
139-
<https://github.com/openedx/paragon/pull/1388>`_
94+
- `Design tokens ADR
95+
<https://github.com/openedx/paragon/pull/1929>`_

0 commit comments

Comments
 (0)