Rails: Drop jQuery as a dependency

Created on 31 May 2016  ·  62Comments  ·  Source: rails/rails

We should now be able to write our data-remote, data-confirm, XHR wrapping, and the few other hooks we rely on using vanilla JavaScript. Things have progressed well enough for that. This is not a verdict on jQuery. There are still plenty of other reasons for someone to want to use that, but it needn't be part of the default stack any more.

//cc @sstephenson @javan

attached PR good first issue railties

Most helpful comment

Actually I'm working on jquery-ujs rewrite to pure JS. My first test is living in https://github.com/simi/jquery-ujs/tree/no-jquery.

All 62 comments

Actually I'm working on jquery-ujs rewrite to pure JS. My first test is living in https://github.com/simi/jquery-ujs/tree/no-jquery.

I think @pixeltrix wanted to do this as GSoC project, so I'm pinging him here as well.

I think I can't attend GSoC, but definitely I'm really interested in this and I would like to finish it. At least I can provide alternative implementation.

Grabbed assignment for this one. @simi (and others), I'd be happy to review your implementation if you want to see it through.

I do agree that this would make a lot of sense as a GSoC project, or a first patch for a newcomer, as it's a solid self contained change that's pretty straightforward. We'd be doing a disservice to those trying to find a way to get into OSS by handling this ourselves

Sounds like a good time to apply our newest label, good-first-patch!

Note: There's no reason that someone looking to work on this needs to do the entire migration as a single PR -- changing one piece of ujs to not rely on jQuery at a time would make sense

Hey, what form of browser support are you looking for here?

I don't mind personally landing a hand. If browser support needs to work for older IE versions than I doubt it'll save much space because of polyfills but it will still be worth our while.

Don't think that supporting legacy browsers is something we need to have
built-in by default. Happy to go with these baselines:
https://basecamp.com/help/3/guides/account/browsers

On Wed, Jun 1, 2016 at 2:38 PM, Benjamin Gruenbaum <[email protected]

wrote:

Hey, what form of browser support are you looking for here?

I don't mind personally landing a hand. If browser support needs to work
for older IE versions than I doubt it'll save much space because of
polyfills but it will still be worth our while.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/rails/rails/issues/25208#issuecomment-222979199, or mute
the thread
https://github.com/notifications/unsubscribe/AAAKtf_Vg2Vkxiy_HgHQ05jmUG10I87kks5qHX05gaJpZM4Iqa33
.

Ah, https://github.com/hauleth/vanilla-ujs looks like exactly what we've been searching for. @javan do you want to take a look at that? If we can just adopt that, all the better.

vanilla-ujs looks pretty solid, and perhaps we can use it as a starting point. I don't like that it exposes some unnecessary globals (I spotted window.CSRF, window.LiteAjax, and window.matches).

@javan I just checked - it only exposes them for debugging they are not actually required. It will trigger a DOM custom event with ajax:before on form submission which appends the CSRF token.

It is only exposed with https://github.com/hauleth/vanilla-ujs/blob/master/lib/assets/javascripts/vanilla-ujs/csrf.js#L20 - it is not _used_ anywhere sans tests and can be safely removed.

IE8 and below are not supported but then again we shouldn't really support legacy browsers.

LiteAjax and others can be shared, I think this can be easily build into a single module wrapped in an IIFE - other things aren't using window.

@simi vanilla ujs has existed for quite some time. :)

LiteAjax and others can be shared, I think this can be easily build into a single module wrapped in an IIFE - other things aren't using window.

👍

Additionally, it would be nice to use fetch in browsers that support it.

@mhuggins nice. I'm reviewing that also.

That'd be nice

@hauleth What do you think about turning vanilla-js into a Rails PR?

@dhh I know Rails doesn't treat backwards compatibility as an important goal, but only supporting modern browsers will mean maintaining legacy Rails applications is going to be even more challenging. There are still plenty of places where developers are stuck supporting users on legacy browsers.

It would be great if the current version of ujs was kept around and officially supported (maybe renamed ujs-legacy?), keeping jQuery and hence support for older browsers. Assuming the ujs API isn't going to drastically change, it won't be much work to maintain.

@lucaspiller current implementation lives in https://github.com/rails/jquery-ujs. I think it will be still supported and you'll be able to point manually in gemfile to that.

The current approach is to make new default and avoid https://github.com/rails/jquery-ujs.

PS:

I know Rails doesn't treat backwards compatibility as an important goal.

That's not true IMHO.

@lucaspiller What @simi said. The current jquery-based approach would still be available as a plugin, but the default would change.

@dhh I would be pleased.

One of the main ideas in the philosophy of a software framework is to ease the burden of program developer. Rails does this perfectly nowadays by providing a really useful set of tools and libraries.

On the other hand, Ruby on Rails developers often do Javascript code, which in most cases lives in the Rails application itself and always quite often relies on JQuery.

I understand the idea behind this issue is to decrease the number of dependencies. However in reality this change means that most developers will do the manual installation of JQuery as the first step after "rails new [app]".

So -- combining the statements above with JQuery download stats (http://npm-stat.com/charts.html?package=jquery), the question:

Is it really really a good decision?

I think so.

Also you can easily do rails new -j jquery [app]. That is going to keep working and jquery-rails is going to keep being maintained.

I assumed that vanilla-ujs was meant to be a drop-in replacement for jquery-ujs but it currently only fires two (ajax:before and ajax:complete) of the defined UJS callbacks.

@cannikin VanillaUJS wasn't meant as drop-in but it can be extended to one. Whole point was to provide minimal version of UJS that is required to work 90% of my cases.

It wouldn't be hard to add these callbacks for LiteAjax, unfortunately there is no way to make them fire in general case without ugly hacks.

Just wanted to toss in another voice for the legacy supporters. We, sadly, support back to IE8. Totally cool with this, though, as long as there is a reasonable way to continue supporting older browsers.

@Ser1aL Many devs these days are using something like Bower or JSPM to manage their front-end dependencies, removing jQuery as a rails dependency allows devs to manage jQuery just like all their other front-end dependencies, making it far more convenient to manage and maintain projects.

Additionally, it would be nice to use fetch in browsers

See that @sgrif ☝️

@metaskills Stop trying to make fetch happen

First of all I'm really welcoming this idea as front-end performance is an important aspect of all my apps. Even dropping jQuery reduces the overhead quite a bit so I'm happy about this.

There's however one quite important thing that jQuery brought (and vanilla-ujs is currently missing): Namespacing.

One of the great benefit of using jQuery is that everything is done under the $ namespace and by convention this avoids fragile code and won't produce bugs that are hard to find in case someone defines similar variables in the global namespace like matches or CSRF for example.

When working with a vanilla UJS library I'd propose starting with an isolated namespace such as Rails. I expect this to potentially grow in the future if new additions will find their way into the framework.

What do you think about it?

It is great idea. 👍 I think this could be the solution to ugly hack that Vanilla UJS is now. Also I am thinking about using ES6 in next release.

@hauleth What ugly hack are you talking about? (I haven't thoroughly checked the full codebase)

In regards to ES6, I understand that this is quite the way where the world is going but I wouldn't just yet make the switch. Rails is still used by many applications that do need to support older browsers. By switching to ES6 we would rule out any potential patches that make the vanilla-ujs library work with them. Not to mention that the Rails community already has to deal with vanilla JS, CoffeeScript and then ES6 would be on top of that. I personally wouldn't rush this, definitely not for now.

@liquid I assume that @hauleth was talking about transpiling to ES5 from ES6 source.

@hauleth I don't know whether you're aware that we have a GSoC project to do what vanilla-ujs does but with 100% of the existing API and add some new ones if we have time like AJAX uploading. Would you be open to us transferring the repo the Rails organisation and using it as a starting point? We need to have control of the repo and gem for security reasons if we are to make it the default within new Rails apps. We'd still like to keep it as a separate gem so that it's easy to switch to jquery_ujs if you need support for older browsers.

No problem. I doesn’t know that this is GSoC project ;)

Wiadomość napisana przez Andrew White [email protected] w dniu 03.06.2016, o godz. 10:22:

@liquid https://github.com/liquid I assume that @hauleth https://github.com/hauleth was talking about transpiling to ES5 from ES6 source.

@hauleth https://github.com/hauleth I don't know whether you're aware that we have a GSoC project to do what vanilla-ujs does but with 100% of the existing API and add some new ones if we have time like AJAX uploading. Would you be open to us transferring the repo the Rails organisation and using it as a starting point? We need to have control of the repo and gem for security reasons if we are to make it the default within new Rails apps. We'd still like to keep it as a separate gem so that it's easy to switch to jquery_ujs if you need support for older browsers.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/rails/rails/issues/25208#issuecomment-223519538, or mute the thread https://github.com/notifications/unsubscribe/AARzN1_TpQuv9T7wZ08fxk5i33Cq9K7Rks5qH-ROgaJpZM4Iqa33.

@pixeltrix can you please just describe what does it mean that this is GSoC project? I'm heavily interested in this. I went thru vanilla-ujs yesterday to see the differences and also I tried to move more from jQuery to ES5 in my fork to test some approaches. Is someone working on this? Should I leave this to avoid useless duplication?

Anyway I agree that it will be best to write a new rails ujs handler from scratch using latest technologies and transpile it back for compatibility inspired by both rails-ujs and vanilla-ujs.

It will be nice to set:

  1. backward compatibility rules (some vanilla-ujs problems mentioned in https://github.com/rails/rails/issues/25208#issuecomment-223067224)
  2. browser support rules (something was mentioned in https://github.com/rails/rails/issues/25208#issuecomment-222980490)

@simi https://github.com/railsgsoc/ideas/wiki/2016-Ideas#implement-ujs-using-native-javascript

Whilst Rails itself didn't get accepted, it's one of the project's under Ruby's acceptance into the program.

Work has only just started and the student (@liudangyi) was finishing his dissertation last week so there shouldn't have been much duplication yet - which is why I want to try and organise this so it doesn't happen.

@simi There's a more detailed description here. It's a little bit old but provides some information you may be interested in.

Considering the backward compatibility and the modern JavaScript development method, I would suggest to rewrite the whole UJS from scratch and give it a new name such as rails-ujs, since it's no longer jquery-ujs. Old projects can still require jquery_ujs, and new projects would require rails_ujs.

Here's an idea: as long as all the JS is being revamped, how about converting vanilla-ujs to coffeescript when bringing it into rails? That might improve the participation rate from rubyists going forward.

@jjb That would make _coffeescript_ a required dependency though. Gain one lose one?

@waits We can use CoffeeScript to write UJS and distribute it in compiled JavaScript.

@waits the win in dropping the jquery dependency is much smaller js for the end user to download. requiring the coffeescript gem in a rails project doesn't affect the end user. so it's a very different notion of dependency.

@liudangyi Right, of course, thanks.

@jjb Do you have evidence that CoffeeScript is preferred over JS by Rubyists? I for one have come to loathe CoffeeScript, so I'm curious what the basis of your consideration is.

I do not have evidence. My statement was based on coffeescript syntax and grammar being more similar to ruby than it is to javascript.

@dhh @rafaelfranca Which approach is better?
a) Make vanilla ujs code part of rails code
or
b) Create new gem (or extend existing e.g. vanilla-ujs) and point to it from default Gemfile?

I think @liudangyi's approach will be the best.

ActionCable had cable.coffee replaced by cable.js for exactly this reason, I'd prefer that CoffeeScript was avoided as a dependency.

Hello, all. I have finished most of the work now, which is available here. All tests are passed, with some necessary modifications in API. However, I cannot test all the cases, so any reviews or suggestions are welcome. :)

Please do open a pull request with the changes.

On Mon, Aug 1, 2016 at 1:46 AM Dangyi Liu 刘当一 [email protected]
wrote:

Hello, all. I have finished most of the work now, which is available here
http:///liudangyi/jquery-ujs. All tests are passed, with some necessary
modifications in API. However, I cannot test all the cases. Any reviews or
advices are welcome. :)


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rails/rails/issues/25208#issuecomment-236494369, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABdWK5uAmhDAZSCOhP2FEzIY2HcGatTBks5qbYgpgaJpZM4Iqa33
.

FYI, https://github.com/rails/jquery-ujs/pull/474 is finished and ready for review

The vanilla ujs implementation by @liudangyi is now living in https://github.com/rails/rails-ujs

I'll ask to get #26836 updated so the users of Yarn can get this in their default package.json file instead of jquery and jquery-ujs, but we still need to decide how to Rails distribute this to users not using Yarn/npm/Bower, in this case we can:

1) Copy dist/rails.js file directly to Rails (inside of railties? a new gem living under rails/rails? copy to user app when the app is generated?)
or
2) Create a new rails-ujs gem and add it to default Gemfile

What do you prefer?

/cc @dhh @rafaelfranca @pixeltrix @sgrif @liudangyi

I'm partial to #1. It's just one compiled file. Seems a little much to distribute as a gem and make it a dependency. I would have it be part of Action View since it's needed as a baseline for those helpers to work.

But that means that if we need to upgrade that file for security reasons we
need to release rails. I think this make our release process more
complicated. My preference is to have it being managed as node module but
for those who don't have node, a gem should not be hard to create.
On Fri, Nov 18, 2016 at 8:21 AM David Heinemeier Hansson <
[email protected]> wrote:

I'm partial to #1 https://github.com/rails/rails/issues/1. It's just
one compiled file. Seems a little much to distribute as a gem and make it a
dependency. I would have it be part of Action View since it's needed as a
baseline for those helpers to work.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/rails/rails/issues/25208#issuecomment-261530112, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAC66HEHQsZc90Huodlrst56bGImFmF1ks5q_aZwgaJpZM4Iqa33
.

If there's an update, we can also just release that dist file again for people to copy in. Don't think that should be the blocker.

Agree that for people who use a dependency manager, that should be the default. But if we are not committing to that as a requirement at the moment, then I think a single dist file is fine.

But I also don't care THAT much. So if you're very passionate about a gem wrapper, then fine by me.

On Nov 18, 2016, at 18:08, Rafael França [email protected] wrote:

But that means that if we need to upgrade that file for security reasons we
need to release rails. I think this make our release process more
complicated. My preference is to have it being managed as node module but
for those who don't have node, a gem should not be hard to create.
On Fri, Nov 18, 2016 at 8:21 AM David Heinemeier Hansson <
[email protected]> wrote:

I'm partial to #1 https://github.com/rails/rails/issues/1. It's just
one compiled file. Seems a little much to distribute as a gem and make it a
dependency. I would have it be part of Action View since it's needed as a
baseline for those helpers to work.


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/rails/rails/issues/25208#issuecomment-261530112, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAC66HEHQsZc90Huodlrst56bGImFmF1ks5q_aZwgaJpZM4Iqa33
.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

The pull request for this: #27113

What happened to the github repo? https://github.com/rails/rails-ujs is showing 404 not found...did you decide to revert back to jquery-ujs?

Given that it has been merged into actionview, does one still need to install it via npm or yarn? I saw some discussion re: a gem for rails-ujs, will that continue to be maintained? For those of us used to working with gems rather than npm or yarn, I'd prefer the gem route rather than having to remember to update via some other method (e.g. npm/yarn).

Isn't the Working with Javascript in Rails doc now quite misleading? Almost all of the code relies on jQuery. Is an update to this doc on the core team agenda, or are PR's welcome here?

Hi, I will repeat here my opinion about the topic.

Then it is confusing. Following the tutorials of the Unobtrusive JavaScript you get coffeescript errors (silent error indeed), and it should work out-of-the-box.
IMHO the correct behavior would be the opposite, include it so the coffeescripts would work by default, and then if programmer do not want it, simply remove.
But removing JQuery you get the behavior of things not working OOTB, and I think that is as Rails was intended to be.

I'll try to elaborate more my reply:

  • I think JQuery has not been declared deprecated.
  • Most of the codes shared are jquery like.
  • It is easier, compare the typical code for setting event listener + ajax.

Then, I think Rails was created with the intention to be the on the easy way. By default everything should be included, so everything (typical) would work out-of-the-box, the easy way. Look i.e. that all objects are included by default. After, any user could freely attune the config to the application.
But the other way IMO is opposite, with some lacks in the application, and needing user additions for make the typical to work.

Was this page helpful?
0 / 5 - 0 ratings