23

I'm trying to install jQuery in Rails 6.0.0.rc1 via Webpack and I'm not sure what I'm missing but I'm getting the error $ is not defined in the browser console despite being able to compile jQuery.

I've added jQuery with yarn add jquery, so my package.json looks like this

{
  "name": "muladeseis_app",
  "private": true,
  "dependencies": {
    "@babel/preset-react": "^7.0.0",
    "@rails/actioncable": "^6.0.0-alpha",
    "@rails/activestorage": "^6.0.0-alpha",
    "@rails/ujs": "^6.0.0-alpha",
    "@rails/webpacker": "^4.0.2",
    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
    "jquery": "^3.4.0",
    "prop-types": "^15.7.2",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.3.1"
  }
} 

My app/javascript/packs/application.js is requiring jquery from node_modules

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("jquery")

And I've tried to register $ in config/webpack/environment.js by doing:

const { environment } = require('@rails/webpacker')

const webpack = require('webpack')

module.exports = environment

environment.plugins.append(
    'Provide',
    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery'
    })
)

Whenever I add a script in my views with a $ reference I get Uncaught ReferenceError: $ is not defined.

I've checked in StackOverflow answers like this to see if I'm registering incorrectly the key character '$' but I've found only answers suggesting using the ProvidePlugin which I'm already referring to in my configuration.

Also if I explore my app Sources in the browser inspector I do see jQuery code integrated in localhost:3000 >> packs/js so the issue is not that Webpack is not finding jQuery but that the key words '$' and 'jQuery' are not recognised.

I'd appreciate your help debugging this.

alopez02
  • 1,524
  • 2
  • 17
  • 36

6 Answers6

40

I've got what's missing.

In app/javascript/packs/application.js forgot to declare:

window.jQuery = $;
window.$ = $;

So jQuery keywords could be picked up.

alopez02
  • 1,524
  • 2
  • 17
  • 36
11

The code in config/webpack/environment.js should look like this:

environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery'
  })
)

see also https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker

Andrew
  • 4,696
  • 1
  • 19
  • 17
5

I tried a lot of things and some worked and some didn't, and some didn't work in my Docker container. In the end I settled on putting this in app/javascript/packs/application.js:

global.$ = require('jquery')

You need to do yarn add jquery of course.

I'm sure there are better ways but this is the only thing that worked for me so I'm putting it up here in case it helps anyone else.

Jimbali
  • 2,065
  • 1
  • 20
  • 24
  • Happy to help! I've since moved all of my JavaScript into packs so I no longer need this, but there are definitely situations where it is still required, such as when using older libraries that depend on jQuery being available globally. – Jimbali Oct 06 '20 at 16:43
  • 1
    Exactly, my use case is including ace editor to my app. It requires $ included globally. Thanks again – Carlos Roque Oct 07 '20 at 23:51
  • This broke something for me. – John Feb 25 '23 at 19:09
2

This solution worked for me with Rails 6.0.2.2 and yarn 1.16.0 https://stackoverflow.com/a/54906972/2970582

Sathish
  • 1,245
  • 2
  • 15
  • 22
1

As I explained at https://github.com/rails/webpacker/commit/198a1580c7ec26a24ee81a09404fc173e725f032 and https://github.com/rails/webpacker/issues/3116defe:

  1. Use expose-loader version 3
  2. Prefer the inline version of exposing jQuery with expose-loader (documented at https://webpack.js.org/loaders/expose-loader/#inline) by using import $ from "expose-loader?exposes=$,jQuery!jquery" in app/packs/entrypoints/application.js.
  3. Where you use javascript_pack_tag add defer: false. For example it could be in app/views/layouts/application.html.erb with:
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload',
      defer: false %>```     
vtamara
  • 148
  • 6
0

i was trying to upgrade from rails 4 to rails 6. After few hours of debugging , finally i fixed this jQuery loading error.

So here are the steps, I followed :

  1. add jQuery
yarn add jquery 
  1. add expose-loader
yarn add expose-loader  
  1. update config/webpack/environment.js file
const { environment } = require('@rails/webpacker')

environment.loaders.append('jquery', {
    test: require.resolve('jquery'),
    use: [{
        loader: 'expose-loader',
        options: '$',
    }, {
        loader: 'expose-loader',
        options: 'jQuery',
    }],
});

module.exports = environment

  1. update app/javascript/packs/application.js file
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

require("jquery");
  1. restart webpack-dev-server
bin/webpack-dev-server 

Always restart webpack-dev-server, if you update environment.js file.

if you want to use older version of jQuery (Ex: version 2.1.4 )

 yarn add jquery@2.1.4 
Mezbah
  • 1,247
  • 2
  • 17
  • 32