
This Week in Rails: jQuery no longer part of Rails, and more - inopinatus
http://weblog.rubyonrails.org/2016/12/3/this-week-in-rails-jquery-no-longer-part-of-rails-and-more/
======
brianshaler
In a way, it's an end of an era. What jQuery did for the industry when it
first came out was amazing. Normalizing differing browser APIs, making
cumbersome APIs more palatable, providing powerfully expressive query
selectors, enabling fairly trivial plugin development, and the nifty monadic
chaining.

Some of those issues have been addressed by browsers, making vanilla JS a
little less unreasonable. For other bits, rails-ujs provides some niceties
that aren't worth carrying all of jQuery to have. These days most developers
will want to use le framework du jour, and don't need jQuery for DOM querying
and manipulation.

~~~
swalsh
Let's be honest, jQuery was a patch for the IE6 bug.

~~~
xutopia
It was much more than that. jQuery made difficult things easy and paved the
way for future technologies by using browser specific abilities and providing
a unified API for developers to use.

It also standardized around a plugin architecture making it easy for people to
write code others could easily reuse.

If you think there is only one iE6 bug that jQuery helped alleviate you'd be
wrong. There are thousands of quirks/bugs/proprietary crap that jQuery handled
for web developers.

Reducing it to an IE6 bug fix is out of touch with reality.

~~~
igravious
They meant, the bug that was IE6 (all of it).

------
mythz
Pour one out for jQuery!

jQuery was a major productivity boost when first released but it didn't scale
well and encouraged creation of tightly coupled glue code. It's decline being
the result of evergreen browsers maintaining good parity where "vanilla JS" is
now a feasible option and from it no longer being needed in the premier JS SPA
frameworks which scales better and allows for the creation of better
componentized and modular code-bases.

In someways we've digressed significantly and made it ridiculously more
complicated to build a modern web app in contrast to what jQuery gives you
out-of-the-box with a simple script include. Now to create a basic Angular2
App you need to download 32k+ files from npm and become an Angular2 build
master just to setup your development environment and configure your
package/deploy scripts.

You can still go a long way with just Bootstrap + jQuery - which would still
be my goto if I just need to spruce up a web page with some behavior. Although
that's happening less and less and find myself reaching for
VS.NET/TypeScript/JSPM/React as my choice SPA stack which scales well with a
great ecosystem, minimal complexity and maximum utility.

~~~
arenaninja
Yeah I get flak when I still use jQuery in new projects. Why do I use it? It
fucking works, with no need to depend on npm, the application is a lot
snappier than using Angular.

If I move on from jQuery, it won't be to Angular. I tried React, but I also
found it too much boilerplate. I'm trying VueJS next.

~~~
spiderfarmer
I've noticed that the people that ridicule you for using stuff that works
(like jQuery) are the same people that have trouble maintaining their own
older code, because they'd much rather just start over.

~~~
xeromal
With JQeury, you can reference one file and get going. With Angular, my
frustration has been:

* SystemJS - I don't understand what's the problem a lot of the time

* TypeScript tsc deciding that Promise is not a known entity.

* People telling me not to use SystemJS because it's causing me all my problems.

* People telling me not to use Typescript because it's causing all my problems.

* Taking 3 days to switch to something not causing my problems.

* Technology x causing me another set of problems.

------
somecallitblues
I will personally continue to use jQuery for many years to come. It's a lot of
power in few concise lines of code and it really makes sense. And it comes at
the cost of a single request. For the small amount of JS my sites use its
perfect. I don't know why everyone in thread is saying goodbye to jQuery. Are
that many people coding in vanilla JS?

~~~
TekMol
I use plain JS.

Can you give an example of a typical line of jQuery that you prefer over
vanilla?

~~~
mercer
I have an example to which maybe you or someone else can suggest a better
'vanilla' solution. Would love to hear suggestions.

With jQuery I'd often do

    
    
        $(<root-element>).on('click', <target element>, callback);
    

crucially, because events bubble up, even a click on a child element of
<target element> will register as a click on the target element.

in plain js it doesn't seem to work that way. I'd do <root-
elem>.addEventListener(), but I'd run into the problem that the event.target
would point at the exact element that was clicked on instead of the parent
element that I wanted to register clicks on.

Given the structure ".item .inner .title", I can't just check if
event.target.classList contains 'item', because it might only contain 'title'
or 'inner'.

event.path to the rescue! I can simply check if any of the parent nodes _do_
contain the 'item' class. Except event.path doesn't work in safari mobile, so
it needs a polyfill. Plus on every event handler I have to go up event.path to
check.

Obviously it's not that hard to write a helper function that basically
emulates .on(), but I can't help but feel that I'm maybe missing some simpler,
plain solution. Any suggestions?

~~~
losvedir
> in plain js it doesn't seem to work that way. I'd do <root-
> elem>.addEventListener(), but I'd run into the problem that the event.target
> would point at the exact element that was clicked on instead of the parent
> element that I wanted to register clicks on.

Unless I misunderstand, I think you might be looking for
"event.currentTarget". event.target is the element that was clicked on,
event.currentTarget is the element that has the event listener attached.

~~~
mercer
Yeah, but that would then either be 'document' or the 'root' of my
widget/component, no? Not the 'item' which is somewhere in between the root
and the target. $().on() is very convenient in that way.

~~~
losvedir
I see, I missed the "<target element>" part of the call. Well, why not just
attach the event listener to that, then? `querySelector` / `querySelectorAll`
can be called on any old element, not just document.

    
    
        <root-element>
          .querySelector(<target element>)
          .addEventListener('click', function(event){
            // event.currentTarget refers to 
            // <target element> no matter which of its
            // children were clicked
          });
    

Admittedly, this doesn't work as well for _multiple_ target elements. I use a
forEach polyfill which could loop through them, but that could create a lot of
event listeners when possibly you'd only need one higher up. Depends how many
there are, I suppose.

~~~
mercer
The problem with attaching the listener to the 'actual' target is that it goes
wrong when your markup is dynamic and so the target element is not (always)
there the moment you create the listener.

This is why one of the early lessons you learn as a jQuery user is to use
$().on() instead of something like $().click();

Plus, while I don't suppose it's a real performance issue much of the time,
adding an event listener to each of, say, a few hundred items in a list is
probably rather inefficient compared to adding it to the root element of the
list.

------
untog
jQuery is/was incredible, and deserves every single bit of praise heaped upon
it. But it is nice to see coding going back towards "vanilla" JS - it wasn't
so long ago that every JS answer on Stack Overflow just assumed you were using
jQuery and you struggled to find an answer that didn't require it. That's not
the case any more.

------
tn13
Why is everyone on this thread talking if this is an obituary for jQuery.
jQuery is pretty amazing and will continue to be the most popular framework
out there for a long time to come. It is just that rails wont ship with it by
default.

------
aamederen
Can anyone explain when did jQuery start to fall back in the tech era? What
were its failures? It is a bit sad to say goodbye to such an old friend.

~~~
wfleming
Nikanj isn't wrong (and is funny), but I think the other (more justifiable)
reason is that jQuery largely isn't _necessary_ anymore: when it came out,
there were an uncountable number of browser incompatibilities that needed
painting over, and APIs for remote requests, DOM querying & manipulation and
the like were very immature, so a library to make everything usable was
extremely valuable.

Now, those APIs are mature & standardized & it's generally not too hard to
write vanilla JS that works across all the major browsers.

I don't think jQuery has failed, but for the kind of baked-in functionality
Rails wants it's not really needed, and there are good reasons not to pack
another dependency into your framework if it will increase page download size
& is increasingly unlikely to be used by the framework's users.

~~~
mercer
I recall reading that element.querySelector(All) was inspired by jQuery. If
true, it means jQuery was so much of a success that parts of it were
implemented natively in browsers!

(I couldn't confirm this by googling, so if anyone can confirm or deny that
this is the case I'd love to know!)

~~~
gsnedders
To some degree, it's absolutely the case that JS frameworks of the era have
shaped what browsers have done in the late-00s.

I can't remember the detail of document.querySelectorAll; it was first
proposed around the time jQuery was originally released.

element.querySelector I think was largely inspired by jQuery's usage of it (in
part to make it easier to run more of jQuery's selectors natively!).

------
shakna
There's still some discussion around the options [0], for now, the new native
js approach is mandatory, even for jquery users. That might not remain.

Also exciting to see Yarn already being supported [1], though not so excited
that npm support might get dropped entirely in favour of yarn.

[0]
[https://github.com/rails/rails/pull/27113](https://github.com/rails/rails/pull/27113)

[1]
[https://github.com/rails/rails/pull/26836](https://github.com/rails/rails/pull/26836)

------
ralmidani
I use Ember on the client-side. Inside components, jQuery is still very
relevant for things like form input masks, Bootstrap plugins, etc.

jQuery continues to save countless hours over using vanilla JS. And it's even
better when you use it with CoffeeScript.

------
susan_hall
I loved jQuery when it first appeared, but it is from another era, for sure.
The rise of the Single Page Application was one big strike against jQuery.
Frameworks such as Angular 1.0 emerged which relied on jQuery, and the
software built with those frameworks revealed the dangers of mutable state,
especially when combined with something async like Ajax. Anyone who has worked
on a large Javascript project is eventually burned by mutable state. Then
other frameworks such as React and Om Next emerged, which advocated for
immutable data. The team behind Angular realized their mistakes and tried to
fix them, so Angular 2.0 was a radical re-write of Angular 1.0, and yet
despite that, more and more developers continued to flock to something like
React. The immutable frameworks offer the idea that all state should be held
in a single immutable atom, and the views should merely be straight
reflections of the state that is held in that atom. One could still
potentially use jQuery in the background to handle the actual update of the
DOM elements, but there are many other ways of updating DOM elements, and many
of those other methods are more efficient than jQuery, so jQuery's importance
has declined.

Back in 2007, if you wanted to add some simple visual effects to your CRUD
app, then jQuery was like a gift from God. But nowadays, given the complex
systems that people are building, jQuery has less to offer. It never had an
opinion about managing state, so it leaves the core question of building a
large app to other frameworks, and those frameworks have various built-in ways
of updating the DOM, so the ease-of-use offered by jQuery is no longer such a
noticeable advantage.

------
rajangdavis
jQuery was the my first language that got me into coding; I had started
javascript but it became very difficult to write a short amount of code for
some basic things that I was working with back in 2012.

Ruby on Rails was my first framework for developing web applications. I still
use it today, but would remove jQuery as a dependency. I thought it was
strange how much of dependency it was for certain things like deleting objects
for Rails; I guess it was the right tool for the time.

jQuery is/was a beautiful thing in that it was a concise and fairly nice API
for interacting with the DOM. I feel like it was the right tool for the time
but now a lot of developers have come to learn the cost of DOM interactions
especially with mobile browsers. I am not too certain about ES6 but that stems
from my ignorance and not any technical concerns.

I think that while there has been strides in understanding how to make rich
clients with javascript without performance issues, I do not think there has
been anything as simple as using jQuery. I prefer to use Angular now or
vanilla javascript if it is a small scale application and while I
like/understand Angular, it took an incredible amount of time and work to
properly understand what I was doing. Vanilla js can be incredibly performant,
but often times I have had to write 3 times the amount of code to get
something going which is a costly in time and maintenance.

jQuery was literally something that took a day for me to understand as non-
developer. I hope as javascript progresses that API developers focus on
simplicity and ease of use when creating the next big javascript framework.

~~~
dvdhnt
Javascript is a language; jQuery is only a library written in javascript.

I will concede its API became so ubiquitous that it morphed into some kind of
pseudo-DSL.

------
marclave
Really interesting, the replacement is a vanilla js implementation called
rails-ujs and was made by someone who went through Google Summer Of Code!

"The new rails-ujs was developed by @liudangyi as part of Google Summer of
Code, all credits for this goes to him and to his mentor @pixeltrix " \-
[https://github.com/rails/rails/pull/27113](https://github.com/rails/rails/pull/27113)

~~~
jon-wood
rails-ujs has been around for a long time (I want to say since the Rails 3
era, but not certain), the change here is to move that from jQuery to vanilla
JS, just as back in the day it was once migrated from Prototype.js to jQuery

------
mouzogu
i still personally find vanilla js quite cumbersome for dom manipulation but
that's partly because i've grown used to the jquery way.

~~~
mercer
Yeah, it's a bit more verbose, although some of that can be alleviated with a
helper function or two, well enough that it's worth it for me in many cases.

But I still regularly find myself just using jQuery for convenience, as
there's still a bunch of gotchas with plain js.

For example, I rather liked the event.path property to deal with event
bubbling, only to discover that safari (mobile, at least) doesn't support it.
Adding a helper function for that was trivial, but it's still one extra thing
to do, and it makes it just a bit harder for other devs to get going. I ran
into a number of these minor issues.

------
bezzi
Now they just need to replace coffeescript with es6/babel.

~~~
BinaryIdiot
I'm not a fan of CoffeeScript but do they really need to lug the huge amount
of dependencies babel brings along with it? Why not target ES5 with some
ES2015 sprinkles in depending on compatibility and slowly work towards ES6?

~~~
paublyrne
I'm not sure how you slowly 'work towards' ES6. Unless you decide to only
support bleeding edge browsers, you cannot use ES6 or ES7 features in
production applications.

The only way we can use them is through transpiling. This will be the case for
at least another three or four years.

~~~
BinaryIdiot
> I'm not sure how you slowly 'work towards' ES6. Unless you decide to only
> support bleeding edge browsers, you cannot use ES6 or ES7 features in
> production applications.

Not really.

First it depends on your target audience. How new are their web browsers?
Where are you developing your web applications? Some projects I've worked on
have web applications that run in only a single environment so those are easy.
Others I've had highly technical websites that the vast, vast majority went to
using newer web browsers.

Second, pick and choose your ES2015 features. Honestly you don't need ES2015
_at all_ but if you want to use it then some items, like let and const, are
supported all over the place but others, like fat arrows, not as much.

> The only way we can use them is through transpiling. This will be the case
> for at least another three or four years.

Again all depends on your target audience. Maybe? Then again I've never been
the biggest fan of transpiling one language into another just to access a
couple of minor feature additions. It's a huge amount of dependencies, build
time, etc all to support a few minor things.

------
pritambarhate
I somehow still seem to need jQuery. Mainly because I need to use a UI
component, and out there one already exists, which does exactly what I need.
So jQuery gets in as a dependency. Maybe because I have used it for more than
8 years now, I seem to know the jQuery based components well.

Especially times when one needs things like
[https://fullcalendar.io/](https://fullcalendar.io/) and Kendo UI jQuery
becomes a required dependency.

To those, how to you program enterprise systems, without jQuery? Do you any
mature UI toolkits which don't depend on jQuery? I am genuinely interested in
knowing about these.

~~~
cmg
I build pretty simple sites on the public side - mostly restaurants and gyms
and other small businesses. I've been moving away from jQuery for everything
except my ecommerce sites over the past few months.

The back-end administrative panel of those sites is more complex. It uses
Bootstrap, so there's some incentive to include jQuery there, though I don't
always use features that require it. But this is an area I struggle with as
well - there are so many external components, like date and time pickers, drag
& drop image uploads, etc, that aren't easily replaced with vanilla JS
components that have feature parity. Curious to see what others have to say
about this as well.

------
michaldudek
I'm not a Ruby/Rails dev, but why the hell was it ever included? :o Isn't Ruby
a backend language and Rails a backend framework? :o

~~~
paublyrne
It's a full stack framework. You can include JavaScript for your views,
probably most commonly used to show, hide, and insert and remove elements from
the DOM.

~~~
aindhaden
To expand on this, the tool of choice for the frontend part used to be
PrototypeJS. In Rails 3.1 the relevant portions were decoupled and became
options rather than baked-in, with jQuery as the default but still an option
among several: [http://weblog.rubyonrails.org/2011/4/21/jquery-new-
default/](http://weblog.rubyonrails.org/2011/4/21/jquery-new-default/)

------
proyb2
I only use flexbox in CSS and Svelte for raw JS, less code and speedier
workflow. It's more easier when combine Svelte with Redux and transpile with
Rollup. With Sever-side Rendering include, this is so much better and doesn't
force me to stick to one framework.

------
hacker_9
Funny how people here are saying goodbye to jQuery. I'm saying goodbye to
Rails.

~~~
aantix
Why is that?

------
akhilcacharya
Never used RoR, was this just used in the scaffolding system?

~~~
awestroke
No, ujs is used to automaticslly implement RoR functions declared in your
rails templates. Eg, you can add a confirm attribute to a link, which is then
implemented by ujs in the browser, causing a confirm dialog when clicking the
link

------
whatnotests
I misread it as "JRuby" removed from Ruby on Rails and almost jumped for joy.

~~~
faitswulff
Does supporting JRuby add a significant amount of overhead to Rails?

------
EGreg
Finally

------
kimshibal
why not replace jQuery with zepto?

