$ is not defined within a .js.erb view using Webpack 2 in Rails app
asset-pipeline, erb, jquery, ruby-on-rails, webpack
Solution
I recently had a similar error due to the fact that jQuery required in Webpack is not exposed in the `view` folder of my app, therefore not visible in my js.erb files. This was solved by exposing jQuery globally adding the following 2 lines in `app/javascript/packs/application.js`:
import $ from 'jquery';
global.$ = jQuery;
Problem
I'm migrating from assets pipeline to Webpack 2 in a Rails 4 app. Everything seems to work fine, except for the JS code using jQuery within a .js.erb view. The content of the webpack.config.js is as follows (omitted code for fingerprinting and compression): ``` const path = require('path') const webpack = require('webpack') const ExtractTextPlugin = require('extract-text-webpack-plugin') const jsOutputTemplate = 'javascripts/[name].js' const cssOutputTemplate = 'stylesheets/[name].css' module.exports = { context: path.join(__dirname, '/app/assets'), entry: { application: ['./javascripts/application.js', './stylesheets/application.scss'] }, output: { path: path.join(__dirname, '/public'), filename: jsOutputTemplate }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: ['es2015'] } }, { test: /\.css$/, use: ExtractTextPlugin.extract(['css-loader', 'resolve-url-loader']) }, { test: /\.s(a|c)ss$/, use: ExtractTextPlugin.extract(['css-loader', 'resolve-url-loader', 'sass-loader?sourceMap']) }, { test: /\.(woff2?|svg)$/, use: 'url-loader?limit=10000&name=/fonts/[name].[ext]' }, { test: /\.(ttf|eot)$/, use: 'file-loader?name=/fonts/[name].[ext]' }, { test: /\.(jpe?g|png|gif|svg)$/i, use: 'url-loader?limit=10000&name=/images/[name].[ext]' }, { test: /\.erb$/, enforce: 'pre', use: 'rails-erb-loader' } ] }, plugins: [ new ExtractTextPlugin({ filename: cssOutputTemplate, allChunks: true }), new webpack.ProvidePlugin({ $: 'jquery', '$': 'jquery', 'window.$': 'jquery', jQuery: 'jquery', 'jQuery': 'jquery', 'window.jQuery': 'jquery', jquery: 'jquery', 'jquery': 'jquery', 'window.jquery': 'jquery' }) ] } ``` The jQuery library (and others related) is required within app/assets/javascripts/application.js as follows: ``` require('jquery'); require('jquery-ui'); require('jquery-ujs'); require('jquery-datepicker'); ``` As you can see, I've used the rails-erb-loader for .erb files but it doesn't work as I might have expected. When the .js.erb file is rendered, I always receive next error in console: ``` Uncaught ReferenceError: $ is not defined ``` The code within this file is nothing fancy, only includes some JS calling jQuery's $ function: ``` let $messagesArea = $('#js-attachments-messages'); ``` However, within console the $ is defined when I print it, even using a debugger at the beginning of the .js.erb: ``` function $(selector, [startNode]) { [Command Line API] } ``` I've included all the possible combinations I've came up to define the jQuery in the plugins section of webpack.config.js: ``` new webpack.ProvidePlugin({ $: 'jquery', '$': 'jquery', 'window.$': 'jquery', jQuery: 'jquery', 'jQuery': 'jquery', 'window.jQuery': 'jquery', jquery: 'jquery', 'jquery': 'jquery', 'window.jquery': 'jquery' }) ``` Is there any configuration I have not taken into account? Any help would be appreciated to resolve this problem. UPDATE The content of package.json is as follows: ``` { "devDependencies": { "babel-core": "^6.24.1", "babel-loader": "^7.0.0", "babel-polyfill": "^6.23.0", "babel-preset-es2015": "^6.24.1", "compression-webpack-plugin": "^0.4.0", "css-loader": "^0.28.0", "expose-loader": "^0.7.3", "extract-text-webpack-plugin": "^2.1.0", "file-loader": "^0.11.1", "imports-loader": "^0.7.1", "node-sass": "^4.5.2", "rails-erb-loader": "^5.0.0", "resolve-url-loader": "^2.0.2", "sass-loader": "^6.0.3", "style-loader": "^0.16.1", "url-loader": "^0.5.8", "webpack": "^2.4.1", "webpack-dev-server": "^2.4.4" }, "dependencies": { // ... "jquery": "^3.2.1", "jquery-datepicker": "^1.11.5", "jquery-ui": "^1.12.1", "jquery-ujs": "^1.2.2", // ... } } ``` UPDATE 2 I've uploaded a sample app reproducing the error trying to remove a resource and then removing it from the page with jQuery. Sample app