1. V8, which is actually really fast
2. Hype around being _asynchronous_ at the time JS itself started to become more hyped up.
1. V8, which is actually really fast
2. Hype around being _asynchronous_ at the time JS itself started to become more hyped up.
With npm it's also really easy (almost too easy) to take your current folder and push it to npm, making the ecosystem bloom with packages.
$ python -m venv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt
Most IDEs will automatically pick up the .venv folderI admit that I'm not a Python engineer, but I have been in the past—twice!
Since those version ranges of X don’t overlap, it isn’t possible to satisfy both A and B’s requirements. Node can handle this
In pip or composer, those dependencies have to be forked or removed or they will create conflicts.
Suppose I use a LibraryX that provides DataTypeX, and most of the functions in my project operate on DataTypeX. I later add another LibraryY, because it provides a utility function returning DataTypeX. I should be able to take the result and use it anywhere in my existing code. However, if my direct dependency on LibraryX is a different version than transitive dependency on LibraryX through LibraryY, then it may not have the same functionality. In trying to avoid a problem at compile-time, the package manager has introduced a huge potential problem at run-time.
With pip you have to resort to hacky solutions like like pip freeze. It also doesn't solve circular dependencies. Luckily these days the Python world has Poetry, which exactly solves this issue, and might be even better than npm. Unfortunately it's third party and adoption is a bit slow, but I use it for all my projects.
If package A depends on package B 1.0 and package C also depends on package B but 2.0, the order in which you run pip install for A or C will lead to a different version of B. And of course either A or V would break as soon as they hit an incompatibility. Obviously you would notice that only by running the application or tests.
So you have to use pip freeze to kind of generate a semi lock file,and every project uses it in a different way, because you also need different dependencies files for dev and production....and these are just plain TXT files which I don't think it is the best "format" for this.
Then you have these text files but also a "setup.py" which is for the package you produce, but hey you need to read the txt because otherwise you need to maintain them in two places. So you add a Makefile to tie all of this together, and that's another rabbit hole.
Add to this the mess of virtualenvs already explained in sibling comments and you have the perfect storm.
I know that nowadays are things such as Poetry, which work a lot better, but there are a good bunch of tools competing with each other.
To make an analogy, npm feels like using the latest, top of the line Macbook while pip feels like using a Casio calculator from 1985 with an external keyboard. That's the gap I feel between these two tools.
So if you ever use python, try first poetry or any of the other tools, pip is a terrible mess.
What's so "mismanaged" about pip? Honest question, I work with NPM every day but I've never really touched pip so all.
Maybe it didn’t have package signing, lock files, or deduping, but clearly it was popular in spite of those faults.
I hate all of them, use only when it’s almost inevitable, so I can’t really have an objective opinion.
Though it clearly worked well enough to be fantastically successful despite valid complaints about it.
For whatever reason, you could have done this stuff in Rhino - for better or for worse - it's just that nobody ever took it as seriously.
A "people actually used this" framework that had Rhino at its core (well, in one of many ways of using it) was Apache Cocoon (which was maybe more by-default based in XSL/T), only they did something almost ridiculously clever: as Rhino had full support for continuations, they didn't need "callback hell" (or async/await) and could even support pseudo-synchronous code that could block on the user (such as a function which sent the user a form and returned the user's selection, possibly hours later) by storing the continuation state in the user's session.
Wow! I'd only dabbled in Rhino back in the day so this is a neat little bit of history. Teleports me back to when this stuff felt fun...
On the other hand, I never heard of Rhino until now.
At the time, there were JS/CSS/image minifiers in just about every language IIRC. Doing it with Node was a stronger argument to at least save the frontend side of the house from having to find a way to do them with Java or ASP.
During that time period, Java compile times were so slow that using PHP as a frontend that spoke to Java backends with SOAP services was really, really common just to avoid slowing everything on the frontend down with Java.