@@ -29,51 +29,54 @@ SCSS.
2929This effectively means that all MFEs share a large chunk of common styling code
3030with 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
4242Decision
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
7068Consequences
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
7881For context, on a sample development machine, rebuilding an MFE takes roughly
7982one minute, of this, on the same machine, around 3-4 seconds is the time it
@@ -82,58 +85,11 @@ takes to build the theme.
8285By continuing to support the existing theming mechanism, the current mechanism
8386for 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
13591References
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