Javascript utility libraries to know in 2018
blog.bitsrc.io
blog.bitsrc.io
I wrote a checklist with some questions that can help you find potential issues with third party packages:
- [ ] Is the package licensed in a way you can use?
- [ ] Is the package's latest published version free of known security vulnerabilities? (can check with https://snyk.io/vuln/npm:moment)
- [ ] Is the package tested? (there need to be at least some unit tests)
- [ ] Is the package lightweight? (can check with https://bundlephobia.com/, this should be considered alongside the size of the problem being solved)
- [ ] Is the package dependant on no other packages? (0 dependencies = less to worry about)
- [ ] Is the package maintained? (activity in the last year, don't forget to check branches other than master)
- [ ] Is the package popular and widely used? (depended on by lots of other projects, number of stars on GitHub)
- [ ] Is the package well structured and easy to understand? (could you contribute and make changes to it quickly? you may have to!)
Once you do decide to adopt something, it's a good pattern to only import it in one place (like an internal `helper` library) and to reference that in every part of the codebase where it's needed. This is in case you decide to replace it in the future, so you only have to change one place.
For the "is it maintained" part, I like to look at issues and how they are resolved
Curious what the thinking is on this. It's true that development could be happening on a branch other than master, but if that's the case I would expect that to be set as the main branch. Maybe master is used only for releases, but that's still a good way to check activity.
The way it's designed makes code splitting and tree shaking extremely difficult, and the difficulty removing large chunks of the library (i'm looking at you locales) is annoying at best. It's also a pretty heavy library on it's own anyway, as it needs to implement quite a lot of code for legacy browsers that isn't really needed if you are only targeting evergreen browsers (and possibly IE 10-11).
As an alternative, I always recommend "date-fns"[0]. it got a mention in the article, but not nearly enough of one!
Stuff like a "time-range" (both a "computer" value, and a "humanized" one like "10 minutes ago"), and other nice to haves.
There's no reason this can't be a good base going forward though! And for what it does cover, I really like the API.
according to https://github.com/moment/moment/blob/develop/CHANGELOG.md#0... the 0.3.0 release was from 2011.
it's barely 7 years ago. And I'm non counting the fact that the current version is 2.22.2 (so there are at least 2 major ones).
How... how can you tell it's aging?!
Lodash (#1 in this article) is just as old or older than Moment, however I wouldn't call lodash "aging" simply because it has adapted to the new paradigms in the javascript ecosystem and works very VERY well with them (to the point that I'd argue lodash is a pretty good example of how to work with these tools).
Moment still does a great job at what it does, and it's in no way getting "worse" over time (quite the opposite!), however because of some choices made during it's development, it can't easily take advantage of newer developments in the javascript ecosystem.
JS has changed significantly, and is still changing. I'd argue that JS became a "real" programming language over the last 10 years, and because of that a lot of things created in that time aged much quicker than they should have.
Like I (briefly) pointed out in my comment, things like tree shaking, module bundling, code splitting, minification, and the tooling and ecosystem around them have changed drastically in the last 5 years. Now moment will still work great with those things, but it doesn't take advantage of them. And that means that alternatives end up getting a leg up because they do take advantage of them.
Something like `date-fns` is designed with tree-shaking in mind, so if I only want to use the part of it that "humanizes" a time range, i'll only get that code. If I want to provide multiple locales for multiple users, but only have each user download their own locale at runtime, I can do that easily. Not to mention that browser support has changed in the last few years, so most people no longer need to support IE 7, 8, 9, etc... And that means that the code that moment has built up to support those browsers isn't needed on newer ones, but again it's difficult or impossible to build it without that to save size.
To continue the analogy I used at the start of my comment, I'd say moment is week old milk. It's not bad yet, but I wouldn't buy it from the store like that in most cases. Moment is great, I do use it in 2 projects at work because it was the best tool for the job for a long time, and it still works fantastically. However if I'm starting a new project now, i'm most likely going to reach for something else.
Not because it's "newer" or because it's the hot thing right now, but because in all honesty the API of a date management library isn't all that complicated, and switching isn't a large cost. And when those other libraries can provide benefits that moment can't, i don't have much of a reason to stay with these "older" libraries.
Use one object to hold configuration and another to hold state.
https://www.amazon.com/Badass-Making-Awesome-Kathy-Sierra/dp...
This one is even easier to spot because it recommends lodash in 2018
Also sugar.js is dead. I maintain http://agavejs.org, an ES8 based replacement, which is stil going.
Ramada.js is geared around making partial function application easy to do. In general, the utitility functions accept any helper callbacks first, and input data last, and automatically generate a partially applied function if you skip any trailing arguments.
For those of you coming from the Java / C++ / Simula 67 culture, this level of brevity may take some getting used to :-)
Ramda does a really good job of helping you “Stop Writing Classes”, composing functions instead.
(Ramada)
There's probably a handful of functions in lodash that are still useful but why take on the security risk and maintenance of another package dependency if you can just copy a couple ten-liners into your own utils folder? It's not like the world is going to come up with a more performant debounce anytime soon.
I guess lodash also relies on jquery which is in the same boat. es6+ has stolen a lot of its thunder and target-aware transpilation is a better approach to cross browser support
Lodash also differs from the standard lib's implementation, notably it's too permissive. Take this example:
const uhoh = null
_.forEach(uhoh, () => {})
uhoh.forEach(() => {})
lodash's forEach has no problem running on a falsey value (it gives you back the value) whereas standard lib leads you to a TypeError.
Two thoughts here. The standard lib forces the programmer to think more about types, which is a good thing. Second is that lodash's more loosey goosey approach acts as vendor lock-in. In two years, when there's 60 lines and 3 files of separation btwn uhoh's assignment and the _.forEach invocation, you won't know whether it's expected to be null or not. So you won't know if you should replace the code with
uhoh.forEach(...)
or
(uhoh || []).forEach(...)
A standard library that wasn't so anemic would be a grand thing.
Read "a disclaimer" here: https://moment.github.io/luxon/docs/manual/why.html
The small JS and node standard libraries and extensive NPM module universe are both a strength and a weakness. It means developers can do things in JS that they can't in other languages and vice versa.
I guess its a matter of preference and right tool for the job. When I started with JS, I was excited by the number of modules and ease of use. I feel like I've grown tired of that and would rather have a decent standard library so I can focus on coding rather than finding the right module and managing my package.json/yarn/npn/webpack.
I'd never prefer one 'true' way (aka opinionated bs) to organic ecosystem competition.
This is how the industry works these day, and beginners coming from bootcamps are told to pick a framework that way.
The more stars , the better.
There are tons of things that lodash still provides that can't be easily replicated.
Just in the last month or so I've used throttle, debounce, uniqBy, memoize, get, and i'm sure more.
Sure, things like map, filter, find, reduce, etc... are made obsolete, and `Object.values` is a huge win to iterating objects or arrays with the same code, but lodash is far from useless.
And the way the library is structured, pulling in just one or 2 functions is fairly lightweight if you are using a bundler like webpack/rollup.
Not really. `_.map` for example works on Objects, and property access is very nice.
`_.map(object, 'myProperty.mySubProperty')`
vs
`Object.values(object).map(i => i.myProperty ? i.myProperty.mySubProperty : undefined)`
Although that being said, for deep property access like you have, i still reach for lodash's `get`, or more recently i'm beginning to use the new stage-1 proposal for "optional chaining" (also known as null-conditional operator in C#) [0].
That turns your second example into:
Object.values(object).map(i => i.myProperty?.mySubProperty)
And honestly I might even reach for destructuring depending on the use case: Object.values(object).map(({myProperty}) => myProperty?.mySubProperty)
As nice as lodash's syntax is, it can be confusing for those who don't know it, and even I need to step back sometimes when I see it used heavily somewhere and almost replay what is happening in my head.After webpack-ifying our old-ass angularjs app, we're slowly replacing features with React components :)
If you're using something to transpile (eg Babel) your code then you don't really need anything like lodash. es6 has most of the array and object functions you typically want, like map, reduce, filter, Array.from(), etc.
Date formating with Moment.js is really nice, but it's big (30kb) so if you're only using a small part of the functionality it might be better to use Luxon (https://moment.github.io/luxon/index.html) as that should be tree-shakable using Webpack.
But I don't like that it is huge and not modular. And that it is not strict in argument checking and accepts anything without throwing any errors.
Otherwise you should stop using lodash too.
After "smooshgate" I don't think that's a plus point.
Lodash full is 24kb. Mout is 450kb...
Not light weight at all. The advantage is that its modular so your bundles would only include the libraries you require. Oh wait lodash does that. So Lodash is a more lightweight alternative to mout...
Sure, a js library from 2008 will still work great now, however it might not work well with new module bundlers, or it might do something that is consitered "code smell" in newer JS engines which could impact performance.
Newer doesn't mean "better", but it's still useful information to have.
I mean, clearly I'm missing something, lots of devs seem to love it and that can't be for no reason; but every time I've encountered it in code I'm maintaining it's been trivially replaceable with vanilla methods, which makes me wonder what the point of including it in the project in the first place was.
This lib is popular because nobody wants to rewrite these functions manually.
E.g. - https://ramdajs.com/docs/#find
Var find_default = R.find( R.prop( ‘default’ ) )
Var list = [
{ name: ‘Abe’, default: false },
{ name: ‘Bob’, default: true },
{ name: ‘Chuck’ }
]
Find_default( list )
//. -> { name: ‘Bob’, default: true }
(Apologies for gratuitous caps and periods my iPad is forcing in)