1

When you use a Python virtual environment, you can activate it for different projects. Whatever packages are in it will be used by the project code. When you use npm, there will be a node_modules folder where the packages are kept, and this is per project.

In my mind, there's a really logical and straightforward way of handling packages: having a single library for all your projects, a list of requirements per project, and then the project uses the packages from that single library. I believe pnpm has this approach to some extent.

What I do not understand is: why is this approach not the norm? For instance, in Python, I don't even know of anything of the sort. Are there some obvious challenges with this or some obvious benefits to the other methods that I am missing?

1
  • 1
    Most package managers (including NPM) do indeed keep local cached downloaded copies of all versions of packages. When you install packages into a project, the package manager will mostly just copy those required versions across the filesystem rather than needing to re-download them. Commented Jul 13 at 7:15

1 Answer 1

5

Virtual environments (and equivalent) are supposed to be isolated. Sure, most package managers, even pip do download data into a single place. But then each virtual env gets its own isolated copy.

There are few benefits of this approach:

  1. You can easily check what libraries are actually used by your project. It is almost always false that one keeps all dependencies in some list of requirements. That is technically rather hard, since libs depend on libs, which depend on libs, etc.
  2. In fact, you can do the other way around: install dependencies first, and then generate requirements file out of it. This is very useful at the early stage of the project. It is also useful when you want to actually generate the true list of dependencies with fixed versions, so that every user works with exactly the same env.
  3. Once you are done working on some project, you just delete it. And in case of Python additionally remove the virtual env. But how would you deal with those global dependencies? Are you going to manually go through each one of them and check if they are not used by other projects? Once I had such a mess on my pc that I didn't even know how many projects I have. So good luck with that. On the other hand: why would I keep around a library that I'm not using?
  4. When you deploy your code, you really don't want some globally accessible cache on the server. Not when it hosts multiple projects. There's a security risk involved here.
  5. Not to mention that dependencies are often specified by version range, not by concrete version. Say you deploy such code to the server. But server's global cache is different then yours locally. But both satisfy the range. You now may experience different application's behaviour, so error prone. This can (and should) be mitigated by things like docker, but docker is just a better isolated virtual environment, that can be easily moved around. That's all.

The only drawback is that it requires more disk space during development. And sometimes during deployment as well (assuming multiple projects live on the same server). But lets be honest: these are like what? Few wasted MB of disk space? Or maybe 100Mb? Or 1Gb? Noone really cares, disk space is the least expensive resource.

7
  • I was a little unsure what the OP was asking about, but seeing your answer makes me think the OP wants something like the Global Assembly Cache in Windows. Anyone remember DLL Hell? I hope that isn't what the OP is taking about... Commented Jul 13 at 1:09
  • @GregBurghardt Global Assembly Cache sounds exactly like what I have in mind. What's the main issue that GAC caused?
    – David Cian
    Commented Jul 13 at 12:44
  • @DavidCian: DLL Hell. See this and this. Here be dragons. Be thee forewarned. Commented Jul 13 at 15:51
  • 1
    @DavidCian Problems with the GAC are a subset of the problems which stem from a lack of isolation. To the first point that freakish made in his answer above , Python VEnvs attempt to solve isolation in a number of other dimensions beyond just packages (including some environment variables and runtime versions). Yet even VEnvs fall short for operating system dependencies/resources/permissions/etc. In reality people often use Containers to isolate the entire operating system, including filesystem and other resources, because anything which is global/shared can potentially cause problems. Commented Jul 14 at 9:10
  • 1
    @GregBurghardt: there is a reason why the second link you posted above gives an extensive list of "DLL hell" issues, but does not mention GAC. Instead, it contains a link Simplifying Deployment and Solving DLL Hell with the .NET Framework. Though the GAC does not completely eliminate the risk for organizations to shoot themselves in their foot by circumventing the safety measures of .Net assemblies, it has made DLL hell issues a lot less likely. But YMMV.
    – Doc Brown
    Commented Jul 16 at 12:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.