We have a drawer in our kitchen where my wife and I keep all sorts of things: old knives or odd forks, rubber bands, matches, garlic press, old corks, pins, scissors, half packs of chewing gum, scotch tape, partly used birthday candles, coasters, watch batteries, toothpicks and so on.
Basically, everything that lies around and could somehow/somewhen be of some use, but does not really belong anywhere end up in that drawer.
We have of course a box with candles, a drawer with cables and old tech parts, a drawer of tools and many cupboards for kitchen utensils, but all those little things would not fit in there because they are smaller orphans single items that we could not group with anything else that deserves a special container or we simply did not have time to sort and organize it.
Ehi dear, while vacuuming I found this tiny bolt under the couch - do you know from where it fell?
I don't know, just put it in the drawer in the kitchen so we won't lose it.
This is how it normally starts.
Of course if some weeks after we find out that a tiny bolt is missing from our office chair there are few options:
1) we don't remember at all that we found a bolt under the couch and we put that in the drawer
2) we remember but we cannot find it there unless we completely empty the drawer on the table and sort all the mess we have there
Something that usually happens is also that once a year we try to fix that mess and spend a couple of hours going through all the content of that drawer.
Why is a bolt even in here?!? and it's thrown away.
Do we even need 10 different coasters that we collected during over many years of pub crawls?
Is this watch battery full or empty? And most of all, do we even have watches that require these?
Can you start seeing the connection with programming now?
When we are coding, we often end up in situations where we write a small function that could be used in other places. Where do we put it?
It is not generic enough, or complex enough, or tested enough, to deserve an own class or even its own npm module. We just wrote that to remove some logic from a bigger function (and just eventually to avoid some code duplication if we happen to reuse it elsewhere).
It can be phone-number formatter, a wrapper for Http-request adding custom headers, a small method that prettifies error messages. I notice that trying to write smaller and smaller functional methods, I end up with more methods that I am not so sure where to put.
Let's put them into a
shared.js
Or better call ithelpers.js
Mmmh, but the HTTP wrapper is not really just helping, it's a needed functionality for every request, let's put that incommons.js
Naah, than rather http-utils.js
The temptation is very big. But try to resist that.
It will spread and in a few weeks, it will contain even more unrelated functions and become bloated. Or, especially if in your project work more than 3 people, you will end up with many commons / shared / helper files. And many of those will contain similar functions.
Yes, there will still be duplication, because when you need to write a small function in a big project you won't be aware of all the small functions written one year ago from a colleague in a completely unrelated part of the application.
And when you look at the file, you will always be wondering, as when I am staring at our junk drawer. What the heck is in there? How am I supposed to find stuff there?
Yes, naming things is hard and so is organize them and try to group them together.
Try to name your packages/files after what they provide and not what they contain (because if they contain a miscellaneaus sorts of things they might end up named misc.js
which is not telling much at all..) and learn to live with the fact that some duplication is unavoidable, and that some duplication is better than the wrong abstraction.