
To manage dependencies in a project, node.js, like many other platforms, provides its own package manager, npm. And despite the fact that it looks similar, for example, to Ruby Gems, and seems to perform the same functions, npm has some features that should be considered when developing applications for node.js. One of these features is the way the node_modules directory is stored in the project. Many, by analogy with other systems, leave in the project only package.json with fixed versions of modules, and node_modules are added to .gitignore. Such a strategy is not always correct, if we turn to the
FAQ at
npmjs.org , we will see the following there:
Q: Should I store node_modules in git?
A: Mikeal Rogers answered this question very well:
http://www.mikealrogers.com/posts/nodemodules-in-git.html
tl; dr
- Store node_modules in git for projects you want to deploy, such as websites and applications.
- Add node_modules to .gitignore for libraries and reusable modules.
- Use npm to manage dependencies in the dev environment, but not in the scripts used for deployment.
Under the cut translation of the article Mikeal Rogers, which describes in detail what is connected with this unusual approach.
One of the problems that required rethinking in the node.js world is the issue of dependency management of an application.
One of the big changes that came with node 0.4.0 was support for node_modules. This change had serious consequences. It raised the priority of local modules in a local directory over modules installed globally. At the same time, npm changed the default setting from global to local and we saw an almost unanimous transition to local modules.
')
Switching from global to local modules is what distinguishes a node from previous generation platforms. Ruby and Python have completely failed in this area, and the fact that development has become a standard practice and deployed in an isolated sandbox for the entire platform (virtualenv, rvm) is a recognition of failure.
But the situation is improving. Support for local modules in a node allows you to achieve what none, known to me, the platform has not yet done, it allows two dependencies to connect completely different versions of the same module, without any conflicts and unintended consequences. This required some advanced logic in the kernel in order to resolve module names locally and recursively. But the most important condition for such support was that no one should ever expect that dependencies at the module level will be global for the entire node process, although this approach has been imposed by the community for some time.
Now we have become accustomed to local modules, have become accustomed, despite some nagging at an early stage. And yet we hold on to the old habits that we have from the old global days.
When we dealt with global installations, and especially with the advantage of global modules over local ones when resolving name conflicts, storing dependencies in a version control system was a very bad idea. This is bad mainly due to the fact that it is an open lie. The presence of a dependency code does not mean that it will be used if the same module is installed globally. We developed heavy deployment tools to make sure that when the code is deployed in one place, and a week later the same code is deployed in another place, both installations will receive the same set of dependencies. All these tools are clumsy, because the problem itself is clumsy.
But now it is no longer Ruby or Python, it is node.js, and we made the modules much better. If you have an application that you deploy, place all dependencies in the node_modules directory in the version control system. If you want to use npm for deployment, connect these modules
only to bundleDependencies. If you have any dependencies that need to be compiled, don't forget to commit their code and just run npm rebuild if it is not complete.
Everyone to whom I told this told me that I was an idiot, and then, after a couple of weeks, they said that I was right, and that placing node_modules in git was a blessing for deployment and development. This is objectively better, but here are a few questions / complaints that arise:
Why don't I just fix the versions to ensure that all installations get the same dependencies?A version fix can only fix versions on top-level dependencies. You fix the express of a specific version and unfold on the machine three weeks later, npm will resolve the express dependencies again and may get a new version of connect with minor changes that will break your application in the most unpleasant and difficult to debug way, as you learn about This is only when the requests go to the new machine. It will become a nightmare, do not do so.
Why don't we encourage library maintainers to also fix versions of our dependencies?As of today, there are approximately 5,500 packages in the npm registry (
Translator’s Note: data for December 2011, now there are almost 34,000 of them ). Over the past month, more than 600 new packages have been added and more than 5,000 have been updated. For some packages, several updates were released during the week. As a community, we must distribute part of the integration testing. It is impossible for most maintainers to sit and test your package with all the updates that come with package dependencies. That is why library developers should not fix versions and should not commit their dependencies to the repository. We need new people to update dependencies locally and send bug reports. We need to keep the community moving forward and stay on top of the latest versions and new packages.
Only applications requiring deployment should store node_modules in the repository. Package maintainers must continue to define acceptable version limits for their dependencies. This is the only way to keep the community in shape with the amount of changes and improvements that we see in node.js.
Does storing node_modules in the repository create too much unrelated garbage in the source tree?No, you are mistaken, this code is used by your application, it is part of your application, if you pretend that this is not the case, it will lead to problems. You depend on the code of other people, and they make mistakes and produce new bugs, at least you, maybe even more often. Storing all the code in the repository gives you the opportunity to keep track of every line that has ever changed in your application. This will allow you to use git bisect locally and be sure that the result will be the same in production and that all the machines in production are identical. There is no longer any need to keep track of unknown changes in dependencies; all changes, in each line, are available through the version control system.
Ok, great, what do we do now?We summarize.
- Store node_modules in the repository for the applications that you deploy, but not for the libraries that you support.
- All compiled dependencies should store the source code in the repository, not the result of the compilation, and should be collected using npm rebuild if it is fully deployed.
You all who have added node_modules to your .gitignore, delete this sucks
today . This is a relic of an era that we are too happy to leave behind. The era of global modules is dead.