Reputation: 53
We have Nodejs projects, One of them is the main project. We are using this (Main Project) functions in other projects. We install our main project as a package with NPM to other projects, then uses the functions that we need.
But this way making many and tied dependency between main project and other projects. Every time that we change main project, we need to update it's version in other projects with NPM install in other projects.
Please give me your idea for the best practices in this case. How we can handle this dependencies between the main project and other projects?
Thanks
Upvotes: 2
Views: 451
Reputation: 2441
Let's start with the global pattern and wording. If a box of functions is used as a toolbox for other projects, you shouldn't think of it as the main project. It is just a library to be required. Call it a basic library if you like. It is a fundament, it is below the project, not above.
The term main has since long been used as the main entry point of a program. Hence, a main project would be the one and only top-level package, that requires all other packages. As you have multiple projects, the term main project is just not in place.
A framework is a more complex case. It seems that's not, what you are talking about. If it is a common framework, I still would call it framework and not the main project.
Now having set the parts into the appropriate places, let's talk about dependencies. All projects depend on this one toolbox. If this toolbox is well coded, it will work with all projects.
If it does not work with all projects, there is code in it, that is not general, but specialised for a single project. This part of the code is the culprit. The code that is special for a single project, should be injected as a callback function. Then the toolbox will execute it, but the special code is still in the codebase of the special project, because the callback is defined there. This kind of callback injection is one of the most powerful parts of javascript.
Then write tests for your code. Writing tests is the best advisor of clean injection and good architecture. I also hint to the term "dependency injection".
All this may sound great, but if you adjust the common library, as a side effect other projects still break, right?
This is not a question of architecture but of maintenance and the release cycle of the library. Projects have to bind to versions they work with. Updates should be done in a semi-automatic way while avoiding conflicts.
There is a common practice of major and minor releases to address this. As you are asking for best practice, the answer is "Semantic Versioning". https://semver.org
The API is extended in minor releases. Breaking changes should only happen in major releases. If you upgrade to a major release, all projects need to be adjusted to the changed API. Hence, breaking releases should be rare, while you should be able to upgrade to minor releases without issues.
A full test coverage of the single project helps to quickly adjust the code to major releases of libraries. The tests reveal every breaking function with one call the tests.
You still need a migration path from your current situation to a satisfying situation. Here the answer is the git repository. Create a branch of the basic library for every project, to keep your business up and running. Then merge the different branches into one abstracted stable branch over time.
So my answer has five parts:
Replace the term "main project" with "base library" in your mindset.
Work with different branches in git as a migration path.
Then learn about injection, injection if form of callbacks and injection of dependencies.
Test your code as far as possible. There are even more reasons to do it.
Finally follow a standard release cycle for the base library.
Following semver your package will cleanly work for the the version based dependency manager of npm
.
Upvotes: 1