Components may reduce the total volume of code you have to write, but keeping them organized can be a nightmare. Here are three simple rules to keep you organized, consistent, and productive.
Building out a front-end website or application using a component-driven approach can do wonders for long-term productivity, but only if you have a consistent approach that keeps you organized.
I keep myself organized by following these three rules:
The ubiquitous example tends to show all components living inside a
components source directory. Something like this:
my-project/ └── src/ └── components/ └── ...
That approach gets unwieldy almost immediately. Instead, I prefer to separate components by the role they play within the larger application.
For example, let's say that I've built my pages such that layout elements wrap template-level customizations, which then include various other components that we call blocks.
Even though layouts, templates, and blocks are (or could be) all technically a type of component, I like keeping them separate from one another. Something like this:
my-project/ └── src/ ├── blocks/ ├── layout/ └── templates/
Depending on the complexity of your project (i.e. the number of source files and directories you have), you may find it more appealing to nest these inside a generic
my-project/ └── src/ └── components/ ├── blocks/ ├── layout/ └── templates/
It's worth noting that some frameworks — Jekyll is one example — are more opinionated about where you place your components without some custom configuration. (With Jekyll, components are more like partial templates, which they call includes). In cases like this, it's usually a good idea to use the framework's defaults.
Even given the structure of the first rule, there's still a very good likelihood that a directory like
src/blocks will get messy quickly. Even small- and medium-sized sites tend to have a fairly large number of components, especially if they are making those components small enough to do one thing and do that thing well.
Therefore, I use some additional logic to decide how to further structure a potentially gigantic directory of components.
Many times a component is only used in one place, by one other component. In that case, it isn't necessary for that component to be exposed right in the primary components directory. Instead, it could be nested within the directory of the component that uses it.
In other words, the top-level of a directory of components should be in use either by more than one other component or by some other type of component.
Consider a case where we have a card component of type block. Let's say the card is only used inside a grid component, also of type block. The card, in turn, uses a button. We also have a header component of type layout which uses the button block.
Visually that comes together like this:
In that case, my directory structure might look like this:
my-project/ └── src/ ├── blocks/ | ├── button/ | ├── ... | └── grid/ | ├── ... | └── card/ └── layout/ ├── ... └── header/
This may or may not be a good idea, depending on how the rest of your project is set up, which is often influences by the framework you're using. It's often better to go with a framework/library's recommendation, rather than creating a whole system that may work against it.
I've found that when a framework can easily support this approach, it's been a huge time-saver. Knowing that all supporting files are in a directory along with a component saves me a lot of digging around.
Supporting files include stylesheets, client-side scripts (for server-side components), or utility files (like adapters and transformers).
I have found it much more efficient to group a component with all its supporting files rather than grouping types of files together. You often see scripts and styles all shoved in the same place. While that makes sense in many cases (especially for global styles and scripts), I've found it easier to locate pesky issues by keeping styles and scripts decentralized and closer to the thing they are affecting.
That said, this requires some additional diligence on your part to ensure you're scoping those supporting files in such a way that they're only affecting the necessary component(s).
Together, these three rules help me stay organized and run efficiently through component-focused sites. That said, one or more of these may not be a great idea for your situation. But I'd love to learn more. What are you using to stay organized? Where do any of these rules not work for you?
It's tough to know when it's the right time to break a component up into smaller components. Here's a way to approach that process that relies on more than what you see on the screen.