Yea, let's bury jQuery again and make more "helpers.js" [1]
export function extend(src) {
var obj, args = arguments
for (let i = 1; i < args.length; ++i) {
if (obj = args[i]) {
for (let key in obj) {
// check if this property of the source object could be overridden
if (isWritable(src, key))
src[key] = obj[key]
}
}
}
}
And the third has been fixed at a community level, as we've learned the value of API strictness, obviating such checks.
I don't think anybody was against jQuery back when the alternative was helper functions, I certainly wasn't. But that's five years ago at this point. Modern JavaScript looks nothing like the code you posted, it's actually been built up into a pretty good language.
You are ignoring browsers support. One of the main reasons I suggest using jQuery is browser support. Another solution is to use a transpiler like Bable.
> Another solution is to use a transpiler like Bable.
At this point in front-end development something like Babel is a must. If you aren't using Babel/Flow/Typescript in your workflow, you are putting yourself at disadvantage for no good reason.
For better or worse, transpiling is a fact of life.
"Five years ago" refers to across-the-board browser support, the spec is older. You can use caniuse.com, https://kangax.github.io/compat-table/es6/, and/or MDN compatibility tables to quickly check browser support. Browsers are now grinding away at new APIs constantly - don't let your memory of "not safe to use" last more than a year.
Corporate and government SOE machines are often running versions 7+ years out of date. I'm still EOL'ing XP machines for government clients. Seniors are another group who often run, well, senior versions.
If your Uber-for-toothpaste startup doesn't care then fine. But crusty old browsers are still a crucial factor in many markets.
If you explore the first of the links you're replying to, you'll see that I make my conclusions about what people are using based on country-adjusted analytics from millions of websites, not imagination.
This situation is actually improving too. Chrome's "evergreen" development cycle has made a world of difference to feature adoption rate, and it's spread to every other major browser vendor. Once IE11 dies out, we'll have no non-evergreen browsers over 1% market share, and it makes me so happy to say that.
Are you absolutely certain that everything that jQuery does can now be done in a clear and concise way using plain Javascript? I've written some fairly complex jQuery selector over the years, perhaps I'm wrong but I something tells me that while the simple use cases can be done with plain old js the more complex selectors might not be so easy.
I find this debate so aggravating. I'm glad you can do some of the stuff jQuery does using modern vanilla js. Perhaps jQuery is overkill for doing one hide/show (or toggle) action on the page. But what about the more complex stuff. What is primary motivation behind this nagging issue, of the load time of jQuery?
I suspect it is that many developers have some obsession over shaving a few milliseconds on their load time. For jQuery? One library? Is it that bad that you need to write vanilla js? So you can save a few milliseconds?
Can you have a sophisticated selector for Event Delegation without using jQuery but make the code concise and easy to read? What about child selectors ("ul.thisClass > li.thatClass" > span.otherClass").
I like jQuery because the syntax makes sense, its clear and concise, you can do complex things with less code. Maybe some of the new stuff can be clean and concise and easy to read, but all of it? I have my doubts.
> Are you absolutely certain that everything that jQuery does can now be done in a clear and concise way using plain Javascript?
Can you give us some examples of things that you're worried can't be written clearly using plain JS? Obviously everything you can do with jquery you can do without jquery. Its just a library.
> Can you have a sophisticated selector for Event Delegation without using jQuery but make the code concise and easy to read?
What do you mean by event delegation in this context?
> What about child selectors ("ul.thisClass > li.thatClass" > span.otherClass")
document.querySelector / querySelectorAll supports this. Its available in all browsers on all platforms if thats how you chose to make web apps: http://caniuse.com/#feat=queryselector
> Can you give us some examples of things that you're worried can't be written clearly using plain JS? Obviously everything you can do with jquery you can do without jquery. Its just a library.
The not() selector for jquery is one. The closest() is another that I have used multiple times.
> What do you mean by event delegation in this context?
This is what event delegation looks like in jQuery;
$("ul#listid").( "click", "li.classThatMatters", function() {
//do something
});
How would event delegation look when selecting a child element with a specific class? Event delegation from scratch in vanilla js is longer than this.
I don't know much about query selectors. I'm going to read up on them. I suspect it handles most if not all the basic stuff jQuery does. However I suspect that are use cases that it might now.
If I understood your event delegation example correctly, I would use event.target.matches inside the event handler. Not the greatest support at the moment though.
And the Fetch API, has, according to caniuse[1], 76% support. I don't know that I can disregard 1 out of every 4 users, hence, jQuery.
For some things, like those mentioned by twhb, where support is >90%, sure, ditch the library and use the supported stuff. But I don't think all of jQuery is that well supported, yet, and/or has as decent an interface.
Polyfills are a good option in some cases. I, personally, try to stay away from them as much as possible. Once you add a polyfill (e.g. fetch), you' soon realize that you need another one (e.g. Object.assign) and soon you will have a list of polyfills to take care of. The advantage of jQuery in this regard is that it has all these "polyfills" in one place.
I believe that jQuery is not "modular" enough for today's web development environment. The "light" version is a step in the right direction but it's not enough. If one could configure the "modules" needed and download/load a single file/library, it would be tremendous.
Event delegation isn't native, but is now possible in five simple lines. That's the pattern: even when there's no native equivalent, new language features facilitate shorter, simpler implementations.
jQuery's performance impact is orders of magnitude worse than "a few milliseconds". On semi-old laptops and on mobile I've seen 200ms in just the time it takes to execute jQuery after loading it. There's also runtime overhead. It's not unbearable, but it's a real hit on a page with high user experience goals.
Native alternatives are often better–thought-out and better-integrated. For example, native Promises have better exception handling (thrown errors can be caught to continue down the "then" chain), more reliable execution order ("then" always defers callbacks, jQuery sometimes executes them inline), and integrate with `await`, like `const data = (await fetch("data.json")).json();`. (Though you should still transpile that, some browsers that don't support it are still in use.)
Besides that, unnecessary abstraction resists novelty and efficiency in the use of underlying resources.
Rather than using a library with a bunch of utility functions that you may or may not need, using individual utility functions indeed does seem like a better idea.
For example, I don't support browsers without classList, so I don't need your regexp stuff. Maybe you do, but my code shouldn't be larger because of that.
Most of these utility functions are fairly straightforward and will rarely require any changes or maintenance. Testing should therefore be straightforward as well. Having the whole community back something doesn't mean it's bug-free, and sometimes it makes it harder when their release cycle isn't as frequent as you'd like it to be.
Having said that, it's all about tradeoffs. Whether your project needs something as big as <insert JS framework or lib here> or if you can live with just needing a few utility functions, you make those choices, doesn't mean one is better than the other as it all depends on context and situation.
jQuery has become the defacto must-use library for javascript now which IMO is unfortunate, as a lot of sites and apps include it when they barely use most of what jQuery offers. I'm guessing most use jQuery for only a few things - Ajax, DOM querying, and events. I hope that sometime in the future jQuery would be more modular.
Dead code elimination (i.e. UglifyJS) should do away with most unused code from a library - so with a proper build system this shouldn't be a big concern...
Not at all, OP said "if one wants to keep things simple with a minimal/nonexistent build system" which would exclude the easiest ways to get one-off utility functions.
Wouldn’t this be an argument for adding those solved problems to JavaScript as like a standard library? I’m not a web developer by day so forgive me if I don’t know all the nuance of JS but I feel like what you would consider it’s “standard” functions is quite small.
That is generally the long term solution, and the reason this website is saying jQuery is no longer needed (because modern browsers offer a much better and more consistent foundation). The problem is the short term. While waiting for browsers to catch up and add new things, we usually have to polyfill, hence this debate.
Those are good links to interesting discussions on the topic, I guess UglifyJS is better than nothing although you're right there.
Are you aware of any alternative that can do tree shaking? Reading those issues' comments there is a link to babel-webpack-tree-shaking [1] which seems to do it?
Rollup [1] seems to be pretty good at tree-shaking and apparently babel's babili minifier [2] is better than UglifyJS (but I guess it's too early to tell)
But both come with their own tradeoffs: Rollup is ES6 only and doesn't support certain features from TC39's Stage 3. Babili is very very new :)
These utility functions and shims are "per" component. This means that functions like extend will be repeated many times in different idiosyncratic code across app.
Imagine your app uses, modals, dropdowns, multiselects, search autocompletes, sliders, rich text areas etc. Instead of having one cached utility library upfront you have many hidden utility libraries scattered around each component, which makes it difficult to say clearly that jQuery is always larger.
The other issue is maintainability. When you're working with third party components, hot-fixing an OS library can be fairly daunting if you need to also learn their own internal class structure, selector helpers, dom manip functions. Doing this in jQuery, it's fairly easy to fork the codebase and plop in a .clone() or .append() to fix a stale issue.
I don't think that burying jQuery is the best idea, too. It is a very well-designed library. What we really need is a library of functions to make the native APIs less awful and verbose - which exists: Zepto.js.
Ultimately mutating the DOM directly is just an awful job - it's solving problems that are ancillary to the problem that you are trying to solve (making great UIs). React and Vue feel like sensible abstractions, although there's still a far better but undiscovered solution to this problem.
Vanilla JS is more about being agnostic to the framework and framework version the developer is using. Not everyone uses jQuery, and if you library depends on it, you now require several tens more kilobytes of bloat to be loaded just for your thing to function.
I've thought a lot about this and honestly I'm curious if this would even be an advantage. Currently I can pull in jQuery from a CDN and it is likely used by many other sites. If I have a custom version of jQuery, now it is guaranteed to need to be loaded. Is it truly a win?
If you're using a build system like webpack you can use Babel/minify to get rid of unused code or pick and choose your modules directly from the npm package.
[1] https://github.com/oncode/handorgel/blob/master/src/helpers....
[2] https://github.com/ThibaultJanBeyer/DragSelect/blob/master/s...