Working with micro-frontends can be tricky sometimes.
With added complexity comes head-scratching bugs that could send you to a mental asylum.
One notorious one I’ve come across was with styled-components where class names collisions occurred between two unrelated components.
If you’ve been suffering from funky CSS styles in your micro-frontend project and you’d like to keep your sanity in check, then this article may be of help to you.

Micro-frontends have been gaining traction for some time and more and more companies are starting to adopt this architecture for their products and services.
Micro-frontends have many benefits such as the ability to isolate team code and being technology agnostic.
Such benefits introduce better productivity for development teams.
They also allow for a more frequent development cycle where features can be released quicker without consulting or coordinating with other teams.
LeafGrow, Leaf’s proprietary growth-engine technology, just recently adopted this architecture for their peerless performance marketing platform and working with them firsthand definitely has shown me the immense benefits that micro-frontends can provide.

What’s the problem with the name collision problem?
To answer this question, we must understand how it even occurs in the first place.

Styled-components are typically installed in each micro-frontend present within your project.
This causes multiple instances of styled-components running at the same time on a single page, which can cause issues such as collisions of class names.
You probably get a console warning as well mentioning this.
Styled-components generate hashed class names for you based on the contents of the css ruleset you have defined, so you could deduce that similar rulesets can create similar class names.
With a single page, running multiple applications, multiple instances of styled-components and multiple similar class names generated, this creates the ultimate recipe for disaster…
A polluted CSS namespace
To solve this issue and avoid it in the future, a few preventive measures can be taken.
1. Styled-components recommends that you run a single instance of styled-components for all your active applications. With webpack, you can use CommonsChunkPlugin which allows you to create shared modules that can be accessed by multiple applications. You can use this to create a vendor chunk that will contain the styled-components module which can then be added as an entry point within your webpack configuration. Refer to this FAQ from styled-component to understand it more.
module.exports = {
entry: {
vendor: ["styled-components"],
app1: "./src/app.1.js",
app2: "./src/app.2.js",
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: Infinity,
}),
]
}
2. Styled-components introduced the ability to add a namespace keyword for the specific instance of styled-components that are running. You can install babel-plugin-styled-components as a dev dependency and add the namespace property for it in your babel configuration file for each micro-frontend application. Each application should have a different namespace. This will separate styles defined in different applications from each other by injecting the keyword within the class name to make it more unique. You can refer to this helpful guide from styled-component.
{
"plugins": [
["babel-plugin-styled-components", {
"namespace": "my-app"
}]
]
}
For me, when I was working on this bug, these two options didn’t work as LeafGrow had a separate custom UI components library for its platform, which ran a separate styled-components instance that is unaffected by the namespace option defined within the micro-frontends.
It was also hard to reproduce locally as the issue never occurred in a development environment, it only occurred in a production environment.
The way I solved this was to use a plain old CSS class name I created for myself.
I took the conflicting ruleset with the generated hash class name and created a wrapper class and applied the ruleset to it.
This is a hacky solution that works very well and can be implemented really quickly but it’s a stop-gap solution that would need to be implemented every time you encounter a collision.
Problem:
The ListWrapper component will generate a hashed class name based on the contents of the ruleset. Any other ruleset with similar properties will have the same class name.
styles.ListWrapper = styled.div`
position: absolute;
width: 100%;
top: 48px;
left: 0;
z-index: 1;
I wrapped the list of css properties with a custom named class which solved the immediate problem.
styles.ListWrapper = styled.div`
.dropdown-list-wrapper {
position: absolute;
width: 100%;
top: 48px;
left: 0;
z-index: 1;
}
In short, we’ve talked about the benefits and challenges of micro-frontends and what it is like to work with styled-components within such architectures.
We’ve also talked about what causes the problem and some preventative solutions as well as a simple solution that can be implemented very quickly if you need to get going with a feature release.
The idea behind this article was just to document this head-scratcher of a bug that took me a while to pinpoint the root cause of and I felt that this could be of use for anybody out there who is trying to get into the world of micro-frontends.
I hope this article has calmed some nerves, alleviated some pressure and has given you peace of mind in knowing what you need to do if you encounter this problem again.
The last thing we need is a mental meltdown!
Stay safe and keep coding what you love!
Leave a Reply