I've been working at Passei Direto since abril/2018 and a few months ago we decided to redo our monolith in angular due to business and code issues. We're in the final stretch of the project, but I already have several lessons that I would like to share if you.
Before the lessons, I want to explain how we divided our website (you can jump for the lessons if you want to).
It's the project that encompasses the micro frontends. Basically it serves to define the shared layout of the site (header and sidebar), to centralize the translations (importing from each micro frontend), to centralize the routes (importing from each micro frontend) and to define the version of each micro front end.
- Lib of components
It's the project that we put all the components we want to share with more than one project. It's a very important project that helps the teams work faster because we tried unifying the design of all pages and components, so sometimes the developer just need to do the logic of the page because all components was already done.
- Api services
It's where we centralize all our calls to api and apply mappers or any treatment for the data returned from the apis.
The name says everything, it's where we put all ours middlewares.
The project that has all the logic we need to do our analytics.
The micro frontend to the user do the payment part of the website. This project it's outside the App because of business decisions.
The micro frontend to the user do the onboarding part of the website. This project it’s outside the App for the same reason from checkout project.
The micro frontend to the user do all the profile things he want to in the website.
- User configurations
The micro frontend to the user do all the configuration of the account in the website.
The micro frontend to the home (we have a lot of subparts for the home) of the website.
The micro frontend to the user be able to interact to our subjects (our website it's a platform of study, because of that we have a subject part).
- Material viewer
The micro frontend to our especial modal. When we close the current modal the last page has to be exactly the same as before (same scroll position inclusively) and acts like page (has a new route).
To be able to do the transaction between angular and vue projects we used nginx reverse proxy to choose the right project to open.
Finally let's go to the lessons:
- It's almost mandatory create a lib of components to avoid replication of code and maintain a unique design;
- The lib of components it's powerful but "with great power comes great responsibility". Imagine the problem of insert a bug in the button component… We learned to have extra care when modifying components here;
- It was a bad idea not to have documented the components of the lib of components because there were 3 teams working on it and sometimes one team build a component and other team build something very similar and no one noticed;
- Not having a documentation of the components led to spend more time to understand how to use a component and if a specific component existed already;
- The lib of component is very critical because it can break parts of the website that the developer can not even imagine and we do not have tests for it yet (for n reasons that do not fit here) but I find it extremely dangerous. I good thing to do here it's check if the coverage of tests decreased. Read more about this here;
- Util create a document with patterns, the code of two teams was very different. After the document, was just different;
- Each project has the same folder structure and this is very good to the developer know where to find what he's looking for;
Every project looks like this:
- It was a great decision to split the page in modules as as exemplified above so all the parts of the respective module was centralised in one place;
- We put a prefix per project in all sccs classes to make it easier to trace which project that class is defined;
- We used scoped css for our components. Before that was crazy to know which scss class was overwriting my class even with the prefix;
- It's difficult to maintain the balance between a non-generic component and a very generic component;
- It was not a very good idea to use vuetify because all components we wanted to customize and that is risky. One thing that happened was that we updated the vuetify version and broked several customisations because they changed the names of their css classes. Now we use vuetify when the component it's complex and it’s not worth building from scratch because it would take too long for that;
- Dividing into micro frontends makes it easier to keep the code cleaner and more organised because it maintains only the context and what is needed for that part of the business;
- Dividing into micro frontends also allows each project to be deployed without compromising another part of the website;
- Vuex was essential to the be able to sync easily the data between the projects. We also used namespace to dived better the store;
- Because we have a lot of micro frontends, new developers sometimes get confuse to know where some code is;
- Another bad thing of having a lot of micro frontends is that you have sometimes to have a lot of visual codes opened to change all you need and that's, believe me, can be very confusing;
- We have route lazy loading to decrease the bundle size and this is good for the use;
- As we use the app as the centraliser of the other projects we have to use the npm link to be able to develop the features and see the change reflected in the app. Often this do not worked as aspected (bugs everywhere) and we did not know why, resulting in deleting the node_modules, re-install and link all over again;
- We centralised all ours shared enums in one project (api services) to not replicate code and avoid crazy bugs. It’s good for our sanity;
- We also centralised all ours shared utils in one project (lib of components) for the same reasons of the enums;
- Dividing into micro frontends it’s excellent if you have a lot of teams. Each team can take care of one project and others teams don’t have to even see the code. This also avoid major merge conflicts;
- Do you remember the material viewer (our special modal)? We use dynamic keep-alive to maintain the context of the previous page with low coast and automatic approach. Read more about this solution here;
- A very good thing was that the design team think the pages as a lot of components and knows the importance of reuse them. Basically we're stating to do system design.
If you've any question, suggestion or anything else please send me a message 😁