This content originally appeared on Bits and Pieces - Medium and was authored by Fernando Doglio
Writing code and publishing it as a component is no longer enough
Everyone knows that by definition a component should be reusable, otherwise, why would you want to turn that code into a component in the first place, right?
Well, while everyone might know that, not everyone is aware of the best way to make a reusable component. And sometimes the end result is a sub-optimal implementation that while reusable, could definitely be better.
So let’s take a look at some of the best practices I’ve come to learn over my years as a software developer.
Modular design
The first thing that should go through your mind when thinking about how to design your new component, is “modularity”.
In other words, your component should be seen as a lego brick, a piece of a larger construct that while working perfectly fine where it is, could also be (metaphorically) moved somewhere else where it makes sense, and it would work just as good.
Building apps with lego bricks is exactly the approach an open-source toolchain like Bit enables. By extracting atomic units of UI into components, and independently storing, testing, and documenting them, you drive composable UI design that scales better, and can be maintained better.
The “where it makes sense” part is important from the statement above, because otherwise you’re asking for a magical component that can fit anywhere.
Instead, focus on-real world scenarios where you could share it, but consider the following:
- There should not be any unneeded external dependencies. Depending for example on React, if you’re building a React component is fine. But depending on MomentJS (to name an example) when you’re building a component that deals with time is not. Instead try to allow for dependency injection of a library with a standard interface, and use whatever you’re given.
- Make sure you properly define the required inputs and the expected outputs. If you expect your component to be modular, part of the design involves defining what inputs it expects so others can code around them, and what values it returns. That way others can make sure it’s compatible with their existing business logic.
Granted, we’re living in the real world, so try to adapt the above ideal requirements to the limitations of your context.
Remember, it doesn’t have to be perfect, it needs to be as good as possible (there is a big difference between the two).
Keep it Simple
The usual KISS principle applies here as well. The Keep It Simple Stupid idea, is that you think about whoever is going to use your component and code for them, not for you.
In other words, try to make their lives easier, and improve the Developer Experience of your module, and everyone will want to use it.
At the same time, as part of the KISS principle, try to keep your components small.
One way I like to think about this is by comparing it with Linux’s CLI tools. There are a bunch of tools for the Linux terminal, and they all follow the same principle: they do ONE thing and they do it right. You can create incredibly complex scripts combining their individual capabilities, but used by themselves they only let you do so much.
The same should be said about your components. Small, composable components allow for a lot more flexibility and reusability than huge, do-it-all components.
And on top of that, you get the extra benefit that smaller, simpler components are a lot easier to maintain and debug. So Win-Win!
Documentation, Documentation, Documentation
I know it sounds boring, but how can you expect people to use your stuff if you don’t let them know how it can be used?
It’s as simple as that, and mind you, I’m not talking about the auto-generated reference page that you can build in 2 seconds with some tools. Those docs might come in handy to you, but not to those who’re just learning about your component and would like to understand how it can be used, what kind of configuration options you added, and if it fits their particular use case. Those developers need more.
They need examples, they need human-written explanations (heck, you can even use ChatGPT now and it would probably work), about each feature, each method, and each option.
That kind of documentation has to be there if you want your component to be taken seriously.
As a plus, you can also allow people to raise issues and ask questions. You can use GitHub for that, if you have the code published there that is. But this gives new users an extra level of security about using your code (after all, they can see you care about your users), and it also gives them the ability to solve any doubts without having to reach out to you (if others have already asked the question).
The tool you use is up to you, really, it can be anything from a GitHub page, to a manually written site or even something like Bit.dev. They allow you to publish your own components in their platform next to the documentation. You can even add live sections to the docs, where people can try to modify your code samples to understand how they work. That’s a great plus and it looks amazing.
Look at the documentation from an old component of mine:
You have a nice UI, live code samples and even a workable test rendered directly on the page. And on top of that, your component is discoverable through the Bit platform.
I know it might not sound like fun, but trust me, in the long run, you’ll be glad you built proper documentation for your components.
Test components thoroughly
This one feels like it should not even be part of this list.
Not because it’s not important, but for the exact opposite reason. I should not be telling you this, you should already know it: tests are mandatory whenever you want to share any code. Even if you’re sharing the component internally with other teams within your own company, the only responsible thing you can do is make sure the code works as expected, and that is done with tests.
Unit tests would be my first suggestion, but if you’re feeling generous, others like end-to-end or even integration tests (especially if you’re building a component that needs to integrate with a proprietary system) are great ideas.
Bit is also a great tool to help you streamline your testing practices, specially so if you’re not that fond of writing and running your own test suites. With Bit, you get:
- Easy integration with popular testing frameworks: Bit supports integration with some of the most popular front-end testing frameworks such as Jest and Mocha. This means that you can easily configure and run tests for your components within the platform. And on top of that, if you’re using another testing library you can integrate it yourself following this detailed guide.
- Automated testing and validation: Bit includes an automated build and validation process that ensures that your components are error-free and functioning as expected. This process can include running tests, linting, and other checks that help ensure the quality of your components. And not only that, but the components are all tested in isolation whenever you prep them for release (automatically I may add).
- Collaborative testing: Bit enables collaboration between developers by allowing them to test and review each other’s components. This can help identify issues and ensure that components are working correctly in a variety of contexts.
Remember: Keep your tests updated and find a way to automate their execution (like with Bit) so you don’t forget to run them whenever you release a new version.
Use semantic versioning
Especially so if you’re building something that others will use. Always try to add some standard versioning system to your components.
That way they’re able to easily understand how a new release can impact them. In the case of semver, which is my favorite one BTW, you can understand if you want the update with a simple look at the new version.
A semver-based version number is composed of 3 numbers: (major version).(minor version).(patch version).
- If only the patch version changed (i.e the third number), you definitely want the update. It means the author published a bug fix.
- If the minor version changed (and potentially the patch version as well), you can choose to ignore it or to get it. It normally means the author published some new features that are backward compatible. So even if you’re not using them, updating the component to that version won’t break anything on your system!.
- If the major version changed, then you better test your code after updating the component. A major version update means there are breaking changes on that component. So keep that in mind before doing the update.
Those are the usual guidelines you should follow, they give your users insight into your updates, so they can easily decide what to do about your new release without having to ask you questions or look for further details in the docs.
If you’re wondering how to implement this into your component library, tools like Bit can simplify the process so much that you won’t even have to think about it that much.
Some of the amazing benefits you get are:
- Automatic versioning: Bit provides automatic versioning for your components. Every time you make a change to a component, Bit will create a new version of the component and track it. You can specify the actual version with the bit tag command or let Bit do its thing and decide for itself. This means that you can easily keep track of changes to your components over time. If you want to know more about how Bit handles versioning your components, read this in-depth tutorial.
- Semantic versioning: Bit supports semantic versioning (there is a reason why it’s my favorite versioning strategy!).
- Version management: Bit provides tools for managing versions of your components. You can view the history of changes to a component, compare different versions of a component, and roll back to previous versions if necessary. You can check out this video by the devs from Bit showing exactly how to use the component-compare feature.
By using Bit, you can ensure that your components are versioned correctly and that changes are tracked and communicated effectively to users.
That said, releasing a changelog whenever you release a new version of your component is also a great idea. This gives even more details about what you’re publishing in case your users want that level of detail. Just make sure they’re meaningful, saying “Several bug fixes” is not enough, detail what you changed, if there are public conversations or public issues that you fixed, link to them so others have the necessary context to understand what it is they’re adding into their systems.
Convention over configuration
You may not agree with this one, but I love this approach.
The idea behind it is that by default your component should work without any configuration needed. In fact, you can provide some “conventions”, like the naming of CSS classes, of children components or some other convention that your code will pick up on and “magically” use.
Of course, you should always give your users the ability to override those conventions through configuration. That way they can be sure of exactly what they’re doing and have complete control over it.
Do not, never, only provide the first part without the override. Hiding functionality behind convention alone is a terrible DX and one you should always avoid. It takes away the feeling of control over your component that someone using it should have, and when that happens, they don’t trust it.
So yes, provide some “magical defaults”, but always let developers overwrite them as needed.
Consider Accessibility
Just because a component works under “ideal” conditions doesn’t mean your component is ready. That’s a great first step, yes, but what about those users who interact with your component but can’t see as well as your “ideal” user? Or what if they can’t see at all?
“Is my component accessible?”
That should be a question you ask yourself way before you call it “done”. Especially because checking for accessibility issues and adding the required code to make it accessible is not a difficult job if done during the development phase.
If you’re wondering what you can do about it, check out this detailed post about all the ways in which you can influence the experience of your users through some extra work on your components.
It’s a lot hard to retrofit accessibility into an existing component, so keep that in mind when you’re planning your next component.
In the end, it’s up to you to decide when your component is “done”. You’re free to publish and share any type of code, but when doing so you should think about those who are going to use it, both from the dev perspective, and from the user perspective.
In both scenarios, you have several considerations that can improve or destroy their experiences and either ensure or negate the success and adoption of your component.
Did I miss any “best practices” you like to keep in mind when designing your own components? Share it in the comments and let’s discuss it!
Build Apps with reusable components, just like Lego
Bit’s open-source tool help 250,000+ devs to build apps with components.
Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.
Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:
→ Micro-Frontends
→ Design System
→ Code-Sharing and reuse
→ Monorepo
Learn more
- How We Build Micro Frontends
- How we Build a Component Design System
- How to reuse React components across your projects
- 5 Ways to Build a React Monorepo
- How to Create a Composable React App with Bit
The Reusable Revolution: Best Practices for Component Development was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Bits and Pieces - Medium and was authored by Fernando Doglio
Fernando Doglio | Sciencx (2023-03-07T07:42:40+00:00) The Reusable Revolution: Best Practices for Component Development. Retrieved from https://www.scien.cx/2023/03/07/the-reusable-revolution-best-practices-for-component-development/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.