You'd have a good point, if all of those tiny but probably useful modules were given the use you're describing.
Discoverability though is so poor that most of those modules are most likely just used by the author and the author's co-workers.
If a typical npm user writes hundreds of packages, how the hell am I supposed to make use of them, when I can't even find them? Npm's search is horrendous, and is far from useful when trying to get to "the best/most supported module that does X" (assuming that random programmers rely on popularity to make their choice, which in itself is another problem...).
The isArray package has 72 dependent NPM packages, it's certainly not undiscoverable. The leftpad package gets 5000 downloads a month, that's quite a bit of testing for edge cases, compared to the none that I would have gotten had I implemented this myself.
Intuitively, this thread wouldn't exist if your assertion were correct.
Write a damn unit test for your padding function. We should share unit tests, not one-line libs.
Libs with unit tests can be one-liners and be as fine-grained as we like, since it's something your users don't have to download
And when a bug is found, instead of fixing it in one place once, you now have to hope that all of your deps and all of their deps update themselves appropriately.
Which is great if you are one person and you fix the bug in your own code. What you're ignoring is that if everyone writes their own version, then the same problem exists. That bug has to be fixed across every (buggy) implementation. A well-defined dependency system where it is easy to discover and update to a new version isn't a matter of hope.
Remember that download counts for package indexes are often misleading. Between scrapers, deployments and continuous-integration systems (all of which download a package -- in the case of CI, sometimes it downloads on every single test run), hitting the thousands-of-downloads level is not hard at all.
Doesn't apply to Javascript, but something like Haskell's hoogle (stackage.org/hoogle could help with a small module approach. It lets you query for functions matching a certain type signature, like this: https://www.stackage.org/lts-5.9/hoogle?q=%5Ba%5D+-%3E+a+-%3...
Because the standard library is where modules go to die. Slaving the release cycle of a library to the release cycle of the language is bad for the health of that library, especially in the case of javascript where code often has to be written to run on old browsers with old versions of the standard library.
Now having a metalibrary that depends on a curated collection of popular/useful utilities is probably a good idea - but isn't that exactly what many of the libraries that broke due to depending on left-pad were?
Yeah, I think the natural question here is: why doesn't TC39 round up all these basic packages and add them to the standard library? I've seen other languages criticized for having too large a standard library, but if this is the alternative...
left-pad was released under WTFPL, so in this particular case there'd be no legal barriers to it. (And I'd assume that, for any libraries with a restrictive enough license, it wouldn't be a hard sell on TC39's part -- if they put out an announcement that they were going to do that, I'd go panning for street cred, and I wouldn't be the only one.)
An alternative could be to pull all this stuff together into one big bucket of Legos and package it with a code analysis tool at the beginning of your build process to strip out everything you don't need from the bucket... but I'd guess that's either already been done or a stupid idea for reasons I don't know yet.
We can't exactly search the code to find out what it does, otherwise you'd basically be reading all the code to discover it's true behavior, which negates the usefulness of modules in the first place...
Any search will have to rely on developer-made documentation, and/or meta data. This is great in theory, but documentation is rarely well maintained, and/or someone changes the code but neglects to update the documentation.
This leaves us with the situation we have today. A search that somewhat works kindof, and mostly you rely on googling the feature you need and looking for what seems to be the most popular choice.
I'm not sure how this situation can be made better, especially if we continue down a path of having all these "one-liner" libraries/modules that anyone can make and stick out there into the unsuspecting world. When I need a square root function, and my search returns 800 one-liner modules, how am I supposed to pick one that I know is reasonably well done, and does what it says it will do, without looking under the hood - you'll end up just picking whatever seems to be popular...
In most languages, things as common as square root would be part of a standard library which everyone uses, so there wouldn't be any question. That also means it would obviously be well-tested and vetted, because everyone depends on it.
Perhaps the solution is avoiding one-liners and moving towards more comprehensive libraries, but that doesn't seem to be what npm devs want (not a JavaScript guy so I'm just observing from the outside).
> Any search will have to rely on developer-made documentation, and/or meta data. This is great in theory, but documentation is rarely well maintained, and/or someone changes the code but neglects to update the documentation.
This is why types are better than textual documentation - the system enforces that they're kept up to date.
We could have something similar with full dependent types a la Idris: you could write a proof and search for a function that satisfies it. If such a thing were popular and huge amounts of Idris code were written, you could write only proofs for your program and the Idris system could go download and piece together your program!
That would be very cool, but I'm not sure how much easier it would actually turn out to be. Also to do anything useful you'd probably have to restrict the language to be non-Turing-complete.
Similar idea but what if you were to write your tests first and then upload them to a site that pieces together the required modules to pass them and generates an API against the modules.
You're totally right. Most developers don't develop this way, and that makes the benefits of this approach far less pronounced than they would be if they did. It also doesn't negate the benefits entirely, of course.
Another benefit of small well understood components is that they are easier to write tests for. Do these npm modules have good test coverage? Did the leftpad module have a unit test that would have caught the issue?
No, leftpad has four test cases and they are all obvious, given the leftpad API.
Would I write tests for my own leftpad implementation if I were not farming it out to a dependency? Its possible. More likely I would want to understand the intent behind using leftpad in my application or library, and have test for "formatTicket" or whatever it is that I'm actually doing. But for all the talk about tiny modules that cover surprisingly tricky edge cases, this is not one of them.
Discoverability though is so poor that most of those modules are most likely just used by the author and the author's co-workers.
If a typical npm user writes hundreds of packages, how the hell am I supposed to make use of them, when I can't even find them? Npm's search is horrendous, and is far from useful when trying to get to "the best/most supported module that does X" (assuming that random programmers rely on popularity to make their choice, which in itself is another problem...).