One liner NPM package “is-windows” has 2.5M dependants, why on earth?
twitter.com
twitter.com
I think there's two things going on here. One, Javascript has taken Don't Repeat Yourself to an absolutely insane extreme. Python claims "batteries included" and Java boasts "there's a library for that", but it's at a higher level than stuff like is-windows.
Most libraries are large and include a lot of functionality, and something like is-windows would be found inside a larger dependency like system-utils. Similarly, a Java dev would import Guava, not immutable-list and and multiset and multilist.
Second, I think many Javascript devs see themselves more as plumbers than developers. The goal seems to be to stitch a bunch of dependencies together to achieve the desired outcome, rather than developing the desired outcome.
I've seen plenty of people rip FileUtils.writeStringToFile out into a standalone utility class, because they didn't need all of commons-io as a dependency. In order to do that, you need to know how writeStringToFile works, and be able to fix whatever breaks when you separate it from its ecosystem.
Devs that pull in is-windows don't have that kind of ... curiosity, I guess is the right word. There's no desire to see how is-windows works, or to see if they can improve it. It does what they need, so they include it as a dependency and move on, end of story. The overhead, and more importantly the security issues, involved just aren't a factor.
I do wonder if the short lifespan of many UI projects is a factor, too. If you're just going to rewrite the UI in six months, there's no reason to make it efficient or maintainable.
Are devs really pulling in is-windows, or are they importing some other thing (that might be more legitimate... that actually uses is-windows)?
If it is the former, man I'm at a loss for words there.
If it is the latter... that would seem to put the onus on the folks writing those other packages.
One time webpack did a breaking change (version 4) right as my team was switching from make + grunt to webpack. It was a total shitshow. Some packages were upgrading, some weren't, some did it wrong and didn't actually work on webpack4. We could have stayed on 3 but then we'd have to figure out which version wasn't broken...
This "argument" gets brought up every time there's an article about NPM. The STD library for node is relatively small so a lot of that work is outsourced to third-party libraries. The node binary is 17mb for mac os x, the node modules for a project end up 100-800mb maybe? So let's say binary + library size reaches 1GB. Now go and download visual studio to work on a C# project and wait for 15GB to be downloaded. I'm not arguing that relying on a third-party ecosystem is great as it does have legitimate security issues, but filesystem size is not the problem here.
A better example would be the .net SDK which is a few hundred MB, but is far more featured.
The npm ecosystem is more comparable to nuget packages, but they are generally at a far more sane scope.
How is that even remotely comparable. Perhaps compare .NET Core SDK vs NodeJS next time.
For example, in CSS, I don't need to import a module with the syntax for Grid, it's just...there, no extra typing required.
For example, take dictionaries (or maps). It lets you use a key (like "bob") to look up a value (like "555-555-1234" or "bob@spam.email").
Dictionaries are built into the language in Python, so to do the above, all you'd have to type is:
phones = { "bob": "555-555-1234" }
In Java, maps are part of the standard library. They're there, but you have to import them: import java.util.*
Map<String, String> phones = new HashMap<>();
phones.put("bob", "555-555-1234");
The main difference is that features in the standard library can be written in the language itself. Java's Map classes are written in Java, while Python's dictionary utilities are written in C.Other than that, the difference is largely semantics.
STD is an apt metaphor for something as promiscuous as node...
`return process && (process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE));`
Here's is what's probably going on in the head of the people who require it:
"What does this do exactly? Why do I need to test against 'win32'? Should I also test against 'win64' or 'x64'? What if it changes later on? Do I need to keep track of Windows versions and then change all my apps? What if I write it without testing for 'cygwin' and someone else in the project do? Will the app only work partially on some hardware? What if some new OS comes out?"
Don't get me wrong, it's not perfect and is a security hole. But that's the reason it's done.
* need to figure out if platform is windows
* stack overflow search (via google) unfruitful
* npm search - popular lib for this!
* it's got a lot of stars!
* yarn add is-windows
process.env.OSTYPE === 'cygwin' || process.env.OSTYPE === 'msys'
Though I don't know enough about V8 to say how each is optimised.Extraordinary package, this.
Just search for "Javascript check if variable is window" to find all kinds of solutions that seem to work at first glance but would probably end up breaking under some specific situations. Some people tests against the .toString of the variable, others look to see if the variable has under it what 'window' usually contains while some create a new instance of 'window' and compare it to their variable, etc.
The solution that "is-window" brings seems to be as perfect as you are going to get it. In an ecosystem where things change quickly and you are not sure where your code is running it's easy to become dependent to such crutches. You do not want the mental burden of remembering all the hacks.
I am not defending this particular package and I'm sure we could come with a better solution of testing it. If you do, make a pull request. I am merely explaining why those package happen.
_Especially_ if it's used by a ton of repos. If, as your example says, something changes where `is-windows` needs to be updated it's likely to either be updated or break so many codebases that someone will update it.
There's a bit of chaotic safety in relying on a web of dependency trust like this. On one hand more people invested in the behavior of a simple package gives you more confidence. On the other hand, it means more developers are depending on more packages, introducing possibly more brittle behavior.
The latter (brittle behavior/deps) has been my experience fwiw. While I don't dislike the idea of `is-windows`, I do dislike introducing more points of random failure. In general if I don't have the idea that my own implementation of something like `is-windows` is likely to need maintaining then I'm happy to do it myself and remove a dependency.
Coming from Rust mostly, but I wonder if the safety of the language aids this problem too. For example, I imagine `is-windows` level of dependencies is far less problematic in Rust than NodeJS.
Besides, the stdlib, and Python packaging in general, is unquestionably light years ahead of NPM.
And yes the setup is more extensive than NPM, which is exactly why the PyPi ecosystem isn’t the steaming pile of shit that is NPM.
You're using some colorful language ITT. "unquestionably light years ahead", "steaming pile of shit", etc. This sort of idiom is good for convincing children. Whom are you trying to convince?
It depends on what you want to do.
The stdlib is of variable quality. I'm happy it's there, but there are absolutely crufty old dragons in there these days, and it updates very slowly compared to pypi.
Node has this phenomenon that some people consider harmful because it is more capable in this particular sense.
Also it's a bit easier to create and publish on npm.
Perhaps someone influential can create an acceptable definition for when it is OK to "repeat yourself". The node.js package dependency culture is toxic.
I have my doubts about that. I suspect it is more a question of what other packages they bring in... that for some reason use is-windows.
I think that is a difference and points to a different set of folks who for some reason, use this thing.
How about fundamentally inane things like giving a cutesy obfuscated name to swallowing exceptions?
https://github.com/electerious/nice-try/blob/master/src/inde...
https://www.npmjs.com/package/nice-try
Used by 1.1 million other packages apparently.
> When I write code, I want to write things semantically— I want to call an isWindows() function, not idiomatically compare a string process.platform (node only) to a string that could change in the future.
> If I have "semantic" functions like isWindows, I want it in a library, not one-off in my project. And if I have a library management system, it's great if the libraries are highly granular— IE, a standard library where each function is one library sounds great.
> …It's just that, instead of maintaining a standard library set containing many small granular sublibraries, the javascript community decided to make every single one-function library an attack/vuln injection surface OH WELL
[1] https://twitter.com/mcclure111/status/1140007877547106305
https://github.com/jonschlinkert/is-windows/blame/master/ind...
If you go read the code, you are doing more than most JS developers do when they pull in a massive sequoia of dependencies.
What if you could do `npm install-inline ./src/utils is-windows` and npm downloaded the module and inserted it inline in your utils directory, along with a comment referencing the original package, version number, and license information (if required). There could be an update-inline command as well.
This seems like a ok compromise between “install 376 micro libraries” and “copy code snippets off StackOverflow”.
The correct solution would be process.platform === "win32" but if you aren't familiar with Windows then you might not realise this includes 64 bit Windows or Windows Server.
If process.isWindows() existed in the standard library nobody would be concerned about it.
No, clearly the people who use this package has not taken even a second to review the code, because it if they had, they'd know that it was trivial. Security-wise, that's deeply troubling.
https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how...
I think there are still going to be things more substantial where the upkeep and testing might be higher where the balance would start to tip back to outweigh the risks maybe, but I think personally I haven't been giving the risks enough consideration and I think thats where NPM needs to focus more of its attention.
Why is you acting like a slow, biological package manager for small bits of code better than using a real package manager for the same purpose?
2. The code you pull in will not get exploited when someone masquerades as the package owner. (How many widely publicized cases of this have there been by now, 5? 10?)
3. Presumably you read the code enough while copy-pasting to be sure it isn't mining Bitcoin or something.
There is many reasons why the copied one liner is better and many why the package manager is better.
Suggestions: series of wrappers for Array renamed as possible applications of Array for those who don’t know what an Array is.
function isWindows() {
if (typeof process === 'undefined' || !process) {
return false;
}
return process.platform === 'win32';
}is-odd 831,460 weekly downloads
These projects seem to have been created and promoted just to boost the author's "npm score" / package count. These micro-modules must cause more problems than they solve.
As for justification and usage I couldn't tell you, apparently it was only used once in that whole codebase anyway (also according to that thread).
[1] https://www.reddit.com/r/programming/comments/886zji/why_has...
What.... why.... the only concievable point of a package like this is that at least it does the kind of type-checking needed to compensate for JavaScripts weak typing system, but why do you need to check the type of String.length?! Do you really think it's going to start spitting anything other than a positive integer? Fucking hell....
var isOdd = require('is-odd');
module.exports = function isEven(i) {
return !isOdd(i);
};1) write actually useful package, get 10k weekly downloads
2) split out 100 utility functions and use them as dependencies
3) magic - your packages now have ~1M weekly downloads. You are now a JS superstar.