One very popular terminal progress bar spinner has over 30 dependencies. One with the list of colors, another to display colors, another to clean the line, another to check if emojis are supported, another one with a list of emojis... plus a whole lot of wheel reinvention.
It was visible that most code in the sub-packages were just functions copied almost verbatim from StackOverflow.
It was also extremely limited when I tried to use it, and had quite a few bugs (it only really worked well on Macs at the time), despite the extremely large number of dependencies. Reimplementing took about 20 lines.
and create another future opportunity for a supply chain attack
require('babel').____secret____.enablePluginFoo = true;
There was no actual plugin API, just selectively-enabled logic hardcoded into the main packages. The whole thing was fake-it-til-you-make-it.Actual plugins for non-standard syntax were all real AST visitor-based modifications, though.
Related projects
----------------
ansi-reset
ansi-bold
ansi-dim
ansi-italic
ansi-underline
ansi-inverse
ansi-hidden
ansi-strikethrough
ansi-black
ansi-red
ansi-green
ansi-yellow
ansi-blue
ansi-magenta
ansi-cyan
ansi-white
ansi-gray
ansi-grey
ansi-bgblack
ansi-bgred
ansi-bggreen
ansi-bgyellow
ansi-bgblue
ansi-bgmagenta
ansi-bgcyan
ansi-bgwhite
That fucking ansi-red "package" has 1.3M weekly downloads.I have to actually check to make sure he doesn't have packages like regexp-left-parenthesis, regexp-dot, etc.
var wrap = require('ansi-wrap');
module.exports = function red(message) {
return wrap(31, 39, message);
};
And ansi-wrap: module.exports = function(a, b, msg) {
return '\u001b['+ a + 'm' + msg + '\u001b[' + b + 'm';
};
Now imagine those things inside a real utility that gets adopted by some popular package.Nobody is asking for the madness of having proper-sized packages split into 100 smaller packages with zero advantages and actually a few disadvantages (difficult to audit, impossible to fork). This is what is being criticised here.
It would be perfectly fine to have a single `terminal-utils` package that contained all of this. And no, handlebar-helpers doesn't count.
> I see this general trend as a symptom of the inadequacy of JS to out-of-the-box address the tasks it's used for, which (as we note here) opens an outlet for spamming and security liabilities.
Two wrongs don't make a right. Package authors should not spam, regardless of the issues with of the ecosystem or language.
Tree-shaking can help at least keeping the build artefact small, but it doesn't help with the codebase during development.
Of course there is still a difference between fine-grained dependencies and things that shouldn't be dependencies in the first place.
Especially when most of those packages are almost never used by themselves, and are instead part of a meta-package with dozens of dependencies.
But I'm with you, this is ridiculous and auditability alone is reason enough to avoid it. Even if you were trying to make a case for composable packages this is absurd to the point that I wonder if it's self aware criticism of npm or an inside joke.
Precisely what? That's not one self-contained package I said is okay.
In the defense of javascript, dead code elimination is kind of hard because it is such a dynamic/messy language and that kind of pushes people in the direction of ridiculously fine-grained modularization. Languages with an actual type system and compiler tend to produce artifacts that only include code that is actually needed. That requires dead code elimination that actually works. Beyond what comes with the browser, there isn't much of a standard library. That's for the same reason. You'd either end up shipping the whole thing on every website or depending on some convoluted tooling in an attempt to strip it down to what you are actually using. Minification is of course a thing but it usually boils down to more obfuscating than actually removing dead code.
My strategy is to generally avoid the whole ecosystem as much as I can. I've been using Kotlin-js lately. Great libraries, runs in a browser, reactive styled components using fritz-2, web compose, or if you really insist react. You still get exposed to some of the madness (like webpack breaking between minor releases) but mostly you are shielded from that.
Yes, it reduces the space cost of having dead code in your build artefact, but it doesn't solve the problem of having dead code lying around during development.
The more code is in your dependencies, the more effort you have in auditing - even if it's only to ensure that code is actually dead - and doesn't cause any unexpected side effects or other behaviour in your program.
export default function isFunction(value) {
const type = Object.prototype.toString.call(value);
return type === '[object Function]' ||
type === '[object GeneratorFunction]' ||
type === '[object AsyncFunction]';
}
This has 120k weekly downloads: https://www.npmjs.com/package/is-fnIs there a site or code snippet where I can see which of the popular dependants was fooled into using this crap and is driving most of the downloads?
> Lightweight - Only one dependency, the excellent ansi-colors by Brian Woodward.
The author's bio on his GitHub profile explains it: he's approaching development with a mindset of sales and marketing. It's also followed by his GitHub stats front and center.
s/projects/functions
isEven claims to be a learning project. It depends on isOdd and isNumber, both of which were admitted (IIRC) to be explicit NPM download boosting projects. Such that the author of isOdd added it to major modules whenever they could
e.g: [1, "one", true, false, 0, "zero", null, undefined]
edit: also ["1", "0", etc]
edit 2: also [NaN]
typeof v === "number"
The rest is parsing territory. “number" == typeof variable
Works for decimals, too.Although maybe you meant to include
"1"
In your examples? "number" === typeof NaN
Returns true. const allowNumbers = {
all: () => true,
notNaN: n => !Number.isNaN(n),
finite: Number.isFinite,
integer: Number.isInteger,
smol: n => Math.abs(n) < Number.EPSILON,
lorge: n => n > Number.MAX_SAFE_INTEGER || n < Number.MIN_SAFE_INTEGER,
}
function isNumber(n, allow = allowNumbers.all) {
return ("number" === typeof n) && allow(n);
}Now, the fact that IEEE754 is insane is something else, but JS does nothing wrong (aside from not having not-floats)
JS has BigInt - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Any weird edge cases against this one?
I wouldn't want to work with this person.
I used to work for a company where it was ok (managers won't say anything, even if explicitly pointed at the situation) to remove company company code, create your own NPM package (on your own private NPM account) and add it as a dependency of the company codebase(s).
This and some other similar behaviours were the reason I left that company. But I'm the loser of the story here, as those guys are now working for even bigger companies with bigger salaries than me.
Another way to look at this is that a lower-paid SWE is paying for their mental health and morale. In my books, that's a winner :)
With the assumption that those engineers whose high/er salary in big/ger companies is not achived through mastery (Netflix is certainly not going to hire the Jon Schlinkerts), they're likely going to work with, say, "moral peers", which is typically undesirable for mentally healthy people.
And you tell me these people don't give a single fuck?
Do people really do this? Does this explain the dumpster fire ecosystem of NPM?
...but interviewers often assume that they are all useful packages and that the numbers are not inflated.
Look at the guys Twitter: https://mobile.twitter.com/jonschlinkert
The sad thing about this is that people will buy it too
And stretching the idea, people who download is-even for serious purposes are probably amongst the hopeless naive/inexperienced ones
You mean how broken it is, and how to take advantage of it? Depending on your business they could fit in really well.
722K of those downloads come from this package by the same authors: https://www.npmjs.com/package/handlebars-helpers-ncc
The handlebars-helpers-ncc package contains 130 different utility dependencies including a few actually useful things like functions to convert Markdown to HTML, but also some weirdly trivial packages like is-even.
I suppose this was a brilliant way for the authors to generate staggeringly high NPM download counts for their packages: Repackage other people’s useful code into convenience functions and then include their own trivial package dependencies several layers deep to multiply their overall downloads count.
I wonder how many jobs they’ve applied to while bragging about their millions of monthly NPM downloads.