The key though is that componentization is useful when you find yourself writing the same code over and over again. That's where DRY steps in and says yeah this should be its own component.
This is one reason monoliths are great as an app structure, because they let you be as DRY as possible and have as few seams as possible (making a component within a monolith doesn't create an external dependency, no seam). Additionally, there are options nowadays (ruby on jets for example) that let you have a monolith repo structure but each controller endpoint gets deployed as a separate lambda. So you get to have your cake and eat it too.
The analogy really does work fairly well at every level of software engineering, from frontend components to backend services.