One of the key realizations we made at Bitovi was that “the secret to building large apps is to never build large apps.” When you break your app into smaller components, you can more easily test them and assemble them into your larger app. We follow what we call the “modlet” workflow, which promotes building each of your components as their own mini apps, with their own demos, documentation, and tests.
- The Modlet Workflow: Improve Your Development Workflow with StealJS
Following this pattern will:
- Ease the on-boarding process for new developers
- Help keep your components’ docs and tests updated
- Improve your debugging and testing workflow
- Enforce good API design and separation of concerns
- Make upgrades and migrations easier
Let’s talk about each of these benefits one by one to see how the modlet workflow can help your development team be more effective.
Ease the onboarding process for new developers
When a new developer starts on your project, they might be intimidated by the amount of files in your app’s repository. If the files are organized by type (e.g. a CSS folder, a JS folder, etc.), then they’re going to be searching across multiple folders to find all the files related to a single component.
The first step to following the modlet workflow is to create folders for each of your components. Each folder, or modlet, should contain all of the files for that component so anyone on your team can find the files they need to understand and develop the component, without having to search the entire project.
Additionally, we build modlets as their own mini apps by including at least the following files in their folders:
- A markdown or text file for docs (if they’re not inline with your code)
- A test HTML page
- A demo HTML page
Those last two files are crucial to following the modlet workflow. First, the test HTML page is for loading just the component’s tests in your browser; second, the demo HTML page lets you see just that component in your browser without loading the entire app.
Improve your debugging and testing workflow
Creating demo and test HTML pages for each component might seem like overkill, but they will bring some great improvements to your development workflow.
The demo HTML page:
- Lets you quickly see just that component without loading the entire app
- Gives you a starting place for reproducing bugs (and reduces the surface area)
- Offers you an opportunity to demo the component in multiple scenarios
That last item can be leveraged in a couple ways. I’ve worked on projects where we’ve:
- Had multiple instances of the same component on a single page so we could see how it behaved in a few key scenarios
- Made the demo page dynamic so we could play with dozens of variables to test a component
Last but not least, debugging issues will be easier because the component is isolated from the rest of the app. If you can reproduce the issue on the component’s demo page, you can focus your attention and not have to consider unrelated parts of your app.
The test HTML page gives you similar benefits to the demo HTML page. When you can run just a single component’s tests, you:
- Don’t need to litter your test code with
.onlystatements that will inevitably be forgotten and missed during code review
- Can make changes to the component and focus on just that component’s tests before running the app’s entire test suite
Enforce good API design and separation of concerns
The modlet workflow also promotes good API design. By using each component in at least two places (in your app and on the demo page), you will:
- Consider exactly what’s required by your component’s API
- Set clear boundaries between your components and the rest of your app
If your component’s API is intuitive and frictionless, it’ll be painless to create a demo page for your component. If too much “bootstrapping” is required to use the component, or there isn’t a clean separation between the component and how it’s used, then you might reconsider how it’s architected.
With your component’s API clearly defined, you set yourself up for being able to take your component out of its original repository and make it available in other applications. If you work in a large company, a shared component library is really helpful for being able to quickly develop projects. The modlet workflow encourages you to do that because each of your components already has its own demos, docs, and tests!
Help keep your components’ docs and tests updated
A common issue I’ve seen on projects that don’t follow the modlet workflow is that docs and tests don’t get updated when the main source files change. When a team follows the modlet workflow, everyone knows where to look for each component’s docs and tests: they’re in the same folder as the component’s source code!
This makes it easier to identify missing docs and tests. Additionally, the files being in the same folder serve as a reminder to every developer on the team to update them when making changes to that component.
This is also helpful during code review. Most tools list files by their name, so when you’re reviewing changes for a component, you’re reminded to make sure the docs and tests were updated too. Additionally, flipping between the implementation and tests is way easier because they’ll be close to each other.
Make upgrades and migrations easier
Last but not least, following the modlet workflow can help you upgrade your app to new versions of your dependencies. Let’s consider an example!
The individual demo and test pages are crucial to making this upgrade. You can start by making the tests pass for your component, then double check it visually with your demo page.
Once those components work, you can start upgrading the components that depend on those:
You can follow this process until you get all of your app’s components working. Then, all that’s left is to test the actual app, which will be far less daunting because you know the individual components are working.
Large-scale migrations are easier when components are contained and well defined. As we discussed in an earlier section, the modlet workflow encourages clear API boundaries and separation of concerns, which makes it easier to test your components in isolation, making an entire app upgrade less intimidating.
Start using the modlet workflow in your app today
You can get started with the modlet workflow today—first, if your team is still organizing files by type, start grouping them by component instead. Move the test files to your component folders and add some HTML pages for demoing and testing your component. It might take your team a little bit of effort to transition, but it’ll be worth it in the long run.
Some of the suggestions in this article might seem intimidating because of limitations in your tooling. For example, if you use a module loader & bundler that requires you to create a separate bundle for each individual page, adding two HTML pages per component would require an intimidating amount of build configuration.
In the next article in this series, we’ll discuss how you can use a module loader and bundler called StealJS to load the dependencies for each of your components without a separate build for each HTML page.
Let me know what you think in the comments! If you follow a similar organization technique, then let me know what’s worked well and what hasn’t worked for you.
- The Modlet Workflow: Improve Your Development Workflow with StealJS
Yeah, our team has found it extremely helpful to use the demos as part of a living style guide. Component libraries are a lot easier to grok when you can play with examples of each component!
We are also using this project structure and have found it to be really useful. In case you are looking for a tool that utilizes this structure to generate a pattern library/design system of of it take a look at the UIengine: https://github.com/dennisreimann/uiengine
I have been using this pattern for years, and the extra work has always proven to be worth it in the long run. Another tangential benefit is when you need to publish a component to npm so that others can use it – all the files necessary to do so are already organized in one place. The effort is usually very small to pull the component into its own directory, initialize git/npm, and push/publish.
I use this pattern for every project, it increases my productivity by reusing components.
As well as the drawbacks?
I already have some ideas but would like to hear from your experiences. Thanks.
I think your choice of library/framework totally depends on your goals. One of the things I love about the modlet workflow is that it doesn’t matter what framework you use—if you’re building your app as a collection of components, then you can reap the benefits of having demos, tests, etc. for each component.
Is it possible to implement the modlet workflow with webpack without losing 2 months setting up the config file?
I will let a webpack user step in to answer this (is there a bat signal for Sean Larkin)?
The next article in the series talks about StealJS, which you can drop into existing projects just for demo and test pages.
Well some frameworks are very opinionated (i.e. ember), you have to follow its design pattern when using it. Anyway thanks for clarification. I see what you mean.
Love the concept. Hopefully I can implement it!