openedx / openedx/frontend-build
[discovery] Apply styles to React component via CSS modules + write ADR
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 25
- Forks
- 41
- Avg merge
- 3d 14h
- Merged PRs (30d)
- 5
Description
The primary mechanism for CSS styles authoring across Open edX micro-frontends (MFEs) is through the use of SCSS. Generally, MFEs will create custom stylesheets and import them from a global stylesheet acting as the styles entry point (example). By doing so, all component-specific stylesheets have access to global tokens (e.g., SCSS variables from Paragon like $primary-500).
The other alternative used through Open edX MFEs is to import the SCSS/CSS file directly within the React component itself. This approach has the downside that Paragon's SCSS variables are not available to these stylesheets when imported in this manner.
However, both of these approaches generally result in all styles getting combined and applied globally across the entire MFE application. The risk of this approach, which has caused style regressions numerous times throughout the years, is that engineers may not know their custom styles are impacting UI unrelated to their specific component(s).
For example, if I create the following component-specific stylesheet and import it using either of the aforementioned approaches, it's override of the .card class name will apply to every single Card in the application, not just my one intended feature.
// MyComponent.scss
.card {
min-height: 10rem;
}
The current workaround to this downside is to make the class name definition have more specificity, whereby the .card styles are scoped to a specific feature/component, e.g.:
// MyComponent.scss
.my-component {
.card {
min-height: 10rem;
}
}
However, needing to rely on specificity to prevent unintended style conflicts/regressions is arguably fairly brittle. Ideally, we could rely on more modern approaches to applying styles to React components. One proposed idea in the past (see discussion) was CSS modules (spec). By using CSS modules, engineers can guarantee their custom styles only apply to their specific UI elements/components, without risking style regressions throughout the entire application.
Example:
// MyComponent.scss
.card {
min-height: 10rem;
}
import styles from './path/to/MyComponent.module.scss';
function MyComponent() {
return (
<Card className={styles.card}>
...
</Card>
);
}
The difference here is that .card is now locally scoped to MyComponent and can never apply outside of this one component.
### Tasks
- [ ] Perform technical discovery around whether Open edX MFEs support CSS modules today. If not, figure out what it would take to support CSS modules. For example, perhaps the Webpack configuration needs to change around the `css-loader` ([docs](https://github.com/css-modules/css-modules/blob/master/docs/get-started.md#webpack)).
- [ ] Write an ADR documenting the support for CSS modules and the recommendation for consumers to start adopting them in MFEs (could be done incrementally).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by examining the frontend-build Webpack configuration, especially the css-loader setup, and verify whether CSS modules are supported for MFE stylesheets. Document the findings, required configuration changes, and incremental adoption recommendation in an ADR, using the linked CSS modules guidance as context.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, scss, webpack
- Domain
- build-system, frontend, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100