Let's start with how they appear. During project development, the programmer tries to put repetitive pieces of code into functions and reuse them. At some point, the same function is needed in two different modules, the inexperienced developer decides to move the function to a separate module. But for some reason stops at this solution, creating a directory/module of utils or helpers, without thinking about the future of this part of the program.
As the project grows, the number of functions in this directory grows. The number of developers in the project also grows. More and more functions appear. Often nobody follows the structure of these modules and it is quite possible that duplicated code will appear.
Forget about the
helpers directories. These names don't really capture the essence of the content. And from the rules of clean code we remember, the name should be unambiguous and reflect the purpose. We have to wonder why we need to put functions in there in the first place. Why are they used in such different parts of the project?
Perhaps the answer is poor organization of the code of the whole project. If you examine the project carefully you can find a lot of code which can be put in a separate library. If this code cannot or should not be put in a proper library, it can be put in a library inside the project. In the case of JS, you can do this by creating a complete library inside
You need to give such a library a meaningful and unambiguous name, write documentation and tests. And all related code should be collected in this library. For example, put all the functions that work with dates in the internal library
lib/ prefix will avoid name conflicts, and it will be possible to use simple and clear names. Of course, you can make an npm scope to simplify future npm publishing. For example,
- All code is put in a full-fledged library with a meaningful name, documentation and tests.
libdescribes the contents explicitly: it's a library.
- Refactoring, publishing and deleting this library become trivial tasks.