7 ms·
One liner NPM package “is-windows” has 2.5M dependants, why on earth?
- netfl0 7y agoThe DRY culture taken to the logical extreme ends up exactly here. Perhaps someone influential can create an acceptable definition for when it is OK to "repeat yourself". The node.js package dependency culture is toxic.
- alexkavon 7y agoI see it as a combination of that and no incentive to review the code you require. We live in a “I need it to just work because everyone wants the dream of tech seemlessly working” age. This will probably become more and more common as the market opens up and the easier jobs (work?) become more and more blue collar. JS lends itself well to entry level devs that just want to write code and not understand needs or how an application works and why code is needed...and the exacerbation continues.
- duxup 7y agoIs this just JS entry level devs bringing in is-windows just because? 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.
- duxup 7y agoAt one point could this have been a more complicated thing to determine and later less so, so the code changed to just the one liner?
- jrvxo 7y agohttps://www.npmjs.com/package/is-odd https://www.npmjs.com/package/is-odd is-odd 831,460 weekly downloads
- _ink_ 7y agoThis is the one I wanted to point out. At least it adds a few type checks.
- SketchySeaBeast 7y agoIt's very easy to flippantly go "why would you ever use that???", but I'm honestly wondering what is the actual justification for the use of such a package. I see it does some initial checking (which will take more lines in your own code to deal with), but I can't figure out why someone would actually use that.
- daxterspeed 7y agois-odd's behavior is also extremely odd. It depends on "is-number" (why would this need a dependency to begin with?), which checks in the most bizarre way imaginable if the input number or string(??) is finite. is-number, and by extension is-odd, also doesn't support BigInts. 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.
- uranusjr 7y agoTo be fair, it is actually far from trivial to determine whether a value is a numeric value in JavaScript, and most all-in-one utility libraries (jQuery, Lodash, etc.) java something of similar functionality. If there is one function that needs its own NPM entry, this probably is.
- tastroder 7y agoThis one year old reddit discussion [1] seems to indicate that the package was used in another, pretty popular and more complex, package by the same author. The dependency doesn't look current anymore but it might be downloads of previous versions. 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_there_been_nearly_3_million_installs_of/ https://www.reddit.com/r/programming/comments/886zji/why_has...
- AdmiralAsshat 7y agoThis kinda of thing (see: the "left-justify" fiasco) seems unique to NPM. Why is that? Python packages are very easy to import as well, but you don't see this kind of madness in most python programs.
- voltagex_ 7y agoPython has a standard library.
- hprotagonist 7y agoand you see the other madness there, in which parts of stdlib are absolute garbage so you will always install requests and lxml anyway.
- Cacti 7y agoI’ve been using Python for 20 years and have never used either of those libraries. People _do_ use Python for more than accessing web services and processing HTML, you know. Besides, the stdlib, and Python packaging in general, is unquestionably light years ahead of NPM.
- jessaustin 7y agoOh wow am I glad to read that! What is the python equivalent of "npm publish"? What do I need to install and configure in order for that to work?
- Cacti 7y agoIt’s “twine publish”... 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.
- jessaustin 7y ago
- tonyedgecombe 7y agoI wouldn't use it but I can see why this might happen. 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.
- datpuz 7y agoI'd argue that having the function process.isWindows() would be a bad design. You'd then need to add process.isMacOS(), process.isLinux(), etc. You can do a switch statement on process.platform.
- tonyedgecombe 7y agoI’m not sure a switch statement against a string is a great solution either although to some extent you are restrained by JavaScripts limitations.
- OskarS 7y agoOk, but lets say you're doing something that requires an isWindows() function. You search NPM, you find this package. At this point, do you not even look at the code? Like, even a glance would make you aware that all it's doing is comparing with "win32", which you can trivially do yourself. So why use the package at all, then? All it adds is overhead. 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.
- slooonz 7y agoWait, do people look at the code of the librairies they’re using in Java/PHP/Python/C++/Go/… ?
- e12e 7y agoDoes it (in)correctly identify ReactOS? That's what I want to know...
- thomascgalvin 7y agoEven the guys on our Node team joke that the node modules folder is abhorrently large. More massive than a black hole is the most common meme. 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.
- duxup 7y agoI asked this in another comment and maybe there is an obvious answer but: 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.
- mcny 7y agoI hate NPM with a passion but even I concede you could argue that this kind of extreme "plumbing" work is an experiment in world-wide collaboration. I mean technically you probably could make a fix in one package and everyone who uses the package benefits from it even without knowing they use the package. While I want to know how stuff works for my personal satisfaction, that's not what business cares about.
- thrower123 7y agoIt's a bit more than `process.platform == "win32"` but the bulk of it is boiler-plate for the insanity of multi-standard JS module definitions. https://github.com/jonschlinkert/is-windows/blame/master/index.js 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.
- datpuz 7y agoThere's also more to it than checking process.platform: 'process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE)
- caspervonb 7y agoChecking for Cygwin is a false positive (IMHO at-least)
- tootie 7y agoI think it's a question of maintenance. You can check if process.platform is "win32" or "win64", but what happens when they release a 65-bit architecture and all your code breaks?
- Operyl 7y agoYour code would break if you pulled in the dependency, too, until you updated it. I don’t think that matters much here.
- tootie 7y agoThen maybe we need a SaaS solution to determinine if we're running on Windows.
- netcraft 7y agoThis is generally my line of thinking - theyre going to be responsible for keeping the package up to date and tested, I dont have to. But this is a good illustration of the extremes of that I think - if they put out a new architecture and it needed to be updated, that would be a major semver bump right? So my code isnt going to be automatically updated and chances are I wouldn't want it to be. And the risk here is huge at the moment - itd be super easy for this package to be compromised and switched out to do something nefarious. 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.
- aethertap 7y agoI will often use things like this, not because I don't know how it's done, but because I have a hope that whoever made it will maintain it and keep it working properly under future changing conditions. Today, it's easy to see if the platform is windows. Later, that may change, and if this code is maintained it will save me headaches. If lots of other people are also using it, there's a very good chance that it will be updated quickly and that weird corner cases I'm not aware of will be already taken care of.
- asdkhadsj 7y agoYea, I agree completely. While I tend to reinvent plenty of wheels, I don't find the idea of importing a package designed for one small task, bad. (edit: missing word) _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.
- brlewis 7y agoSpelling correction: dependents
- caspervonb 7y agoNot in proper real English it's not.
- Raphmedia 7y agoThis line is tested against and super optimized. By requiring this, you are future proof. The maintainer is active and writes tests. It's also a bit esoteric and hard to undestand. `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.
- darepublic 7y agoMy process for requiring it would be as follows: * 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
- OskarS 7y agoYou really think that line is "super-optimized"? It generates and executes a regex to check if a string has one of two different prefixes. I don't know a lot about JavaScript internals, but I would imagine that is both forces memory to be allocated (and garbage generated) as well as being significantly slower than a basic prefix check. If doing this is considered "super-optimized", I don't even know what this industry is any more.
- ChrisSD 7y agoIt's not even testing prefixes, it's testing the whole string. It's the equivalent of: process.env.OSTYPE === 'cygwin' || process.env.OSTYPE === 'msys' Though I don't know enough about V8 to say how each is optimised.
- OskarS 7y agoOh, you're right! I missed the dollar sign! That makes it even worse! Unless V8 converts the regex to that expression (which it could maybe do, but I doubt), there's no way the regex version could be anything like as fast. Your version has the added benefit of also being far more readable and totally without any kind of memory allocation. Extraordinary package, this.
- stupidcar 7y agoI think it's funny how so many people have an allergic reaction to using a package manager to add fragments of small but non-obvious code to their codebase, but have no issue with frequently using Google to track down one-liners on Stack Overflow, which they then copy-and-paste into their codebase. 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?
- tntn 7y ago1. The code you pull in will not get updated unless you do it explicitly. 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.
- gnrl 7y agoThe line of code in that moment is read and "vetted". Same can be done for the dependency yes, but what happens if malicious code is injected later and you update your packages? Or like the leftpad disaster where the package was deleted? There is many reasons why the copied one liner is better and many why the package manager is better.
- frou_dh 7y agoOne-line NPM packages promoting naive excessive code-reuse are eyebrow-raising but not as bad as it gets. How about fundamentally inane things like giving a cutesy obfuscated name to swallowing exceptions? https://github.com/electerious/nice-try/blob/master/src/index.js https://github.com/electerious/nice-try/blob/master/src/inde... https://www.npmjs.com/package/nice-try https://www.npmjs.com/package/nice-try Used by 1.1 million other packages apparently.
- diminish 7y agoHere's an idea. Why doesn't NPM or some big guy maintain a node "standard library" which pulls top 1000 most used small npm packages into a single one?
- kasey_junk 7y agoWhat would that solve?
- WkndTriathlete 7y agoThe best part about that would be the endless arguments about which license was appropriate for the thousand different licenses aggregated together.
- jakelazaroff 7y agoThe reply by @mcclure111 [1] is good: > 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://twitter.com/mcclure111/status/1140007877547106305
- heavenlyblue 7y agoWelcome to the times when we import code by semantics, rather than it’s pragmatics. We’re getting to the next step of evolution in engineering. Suggestions: series of wrappers for Array renamed as possible applications of Array for those who don’t know what an Array is.
- chrisfinazzo 7y agoHumans are stupid and cannot learn anything https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/ https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how...
- tlrobinson 7y agoI’m glad people publish packages like this, but feel like there needs to be a better way to consume them. 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”.
- deleted 7y ago[deleted]