Originally published on Medium on October 25, 2019
ROI Hunter is a Product Marketing Platform created to help e-commerce retailers attain better insight into product performance. The whole application is powered by ReactJS library in combination with TypeScript, where several teams work and are in charge of a specific part of the platform. Individual teams are more specialised within their part of the platform, and it’s easier to solve some things with specific team members during the development. Three smaller projects have been created since the creation of the ROI Hunter application — the Video editor Mia, the image editor TEDI, and UI library UIKit. Now let’s talk more about UIKit.
A UIKit is a UI library where we have all the UI elements we use in ROI Hunter. Like any other project, ROI Hunter began with a difficult decision on which technology to use, how to define the structure of the project, how to work with the stylisation of the whole project, and so on. After a few weeks of work, the idea to unite all UI elements under a new project to bring together styles and components (buttons, inputs, icons, loaders, etc.) began to grow and provide an easy way to share styles and components across multiple projects.
Gradually smaller FrontEnd projects were created in ROI Hunter that needed to be added to the main project, such as our Mia video editor, and we had to ensure that the component styles were consistent. If each project had its own components, any changes would be difficult to track, and we would have to work it out in several different places, with the risk of forgetting to change some projects altogether.
UIKit makes changes easy. You just edit a component in one place and then update the version in your project. UIKit can also be versioned independently of the main project. It is possible to prepare new changes in advance and then only update the version together with the project in which the new changes are incorporated.
For new developers in the company, it may be quite difficult to remember all the components, the different component options, and when to use which component. For this purpose, we used react-styleguidist, which makes it possible to add any number of usage examples as well as various corner cases to each component using examples in * .md files. Newcomers can open this guide and quickly get to know all the components and their capabilities.
However, it is important to put a lot of emphasis on testing, as UIKit could be used by multiple projects, and changes in new versions will, of course, be reflected in all projects after the update. The big advantage is the ability to decrease (reverse?) the version at any time and quickly solve any problems that arise after the update.
Animation by Justin Reyna
For the basis of the whole project, I recommend choosing react-styleguidist. With the help of a small config file, this offers the possibility to present examples of components and a local server for the development of the entire project. For the compilation of the project, you just need to create a config for the webpack. For react-styleguidist in combination with TypeScript, I definitely recommend the react-docgen-typescript package, which can parse types from TypeScript and where it’s not necessary to define the PropTypes for components. Components can be divided into different searchable sections. This gives us a quick and clear way to share components with other developers.
React-styleguidist also understands TypeScript very well. Without this, I would definitely not embark on similar projects. The stability and flawlessness of the whole project comes down to many necessary key features, and thanks to the static typing that TypeScript brings to the project, the work on the project is much safer. At the same time, you can use the TypeScript types for automatic completion in the IDE.
Once the project itself is set up, compiled, and ready to start using in other projects, we have several options to publish the project. A quick option is to publish the package directly to the public npm repository. You can also use other services, such as bit.dev, or create your own npm repository on your server. If you use Github, it is also possible to use Github packages.
With the project itself comes another responsibility — keeping dependencies updated. I highly recommend DependaBot, which takes care of update checks and creates pull requests with individual updates.
Last but not least, we want to make component modifications and package updates as comfortable as possible, so it is very important to ensure proper testing of the entire project. We decided to use Jest and Enzyme with snapshots for unit tests and Cypress to automatically click through all components. Of course, you can also make full use of TypeScript in both cases. Working on the project will then be a breeze for you.
For a project of this scale, it is important to clearly define how to further develop the project, so that anyone who joins the project can easily and quickly add new modifications and prepare everything for inclusion as soon as possible. If UIKit is used across multiple projects, there is a good chance that the developers from the respective teams will want to participate in the development.
I recommend limiting dependencies to the necessary libraries, reducing the time required to update packages, testing, and checking everything. At the same time, it is ideal to store only those packages in dependencies that need to be installed for the project implementation. The rest is preferable to save in devDependencies. I also recommend using peerDependencies, which allows developers to see which packages are needed.
There is no need to describe how the enum can make our lives easier. When we define the props for each component, most of us are looking for the enums that are also available through TypeScript. However, when we use these enums in local development, it is ideal to export the enums together with the components from the project so that they can be used directly in projects.
Individual components should not be too complex as most logic should be implemented by the developer directly in the project. Over time, there may be a tendency to add larger and more complex components, often composed of several UIKit components, but in this case, it is advisable to start thinking about integrating components such as exporting under a different name or creating a new project.
Often developers may have mismatches about which component to include and whether it is appropriate to add a component to UIKit when implementing a task. In this way, different duplicates of components and possibly duplicates directly from UIKit can be created in projects with some custom modifications. In this scenario, UIKit will begin to lose momentum.
Last but not least, adapting styles to projects can be a problem. It may happen that some projects will have specific requirements, and when developing components in UIKit, all of these requirements need to be evaluated and implemented to avoid the tendency to hack styles or components.