Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use jQuery with rails webpacker 3

I generate a new rails app : rails new titi --webpack=vue

and would like to use jQuery (or other libs like popper, vue-resource...).

I tried to yarn add jquerywhich was fine, but I don't have access to jQuery in my JavaScript code.

In previous Webpacker gem, there was much more conf and I had to write this in shared.js :

module.exports = {
    ...
    plugins: [
      ...
      new webpack.ProvidePlugin({
          $: 'jquery',
          jQuery: 'jquery',
    ]
    ...
    resolve: {
      extensions: settings.extensions,
      modules: [
       resolve(settings.source_path),
        'node_modules'
      ],
      alias: {
        jquery: "jquery/src/jquery",
        vue: "vue/dist/vue.js",
        vue_resource: "vue-resource/dist/vue-resource",
    }
}

What is the cleanest way to include libraries in current Webpacker version ? Something in config/webpacker.yml?

like image 330
Kikan Avatar asked Sep 01 '17 10:09

Kikan


People also ask

Does rails 7 Use Webpacker?

Taking into consideration all the major shifts in modern Javascript development, Rails 7 has decided to replace Webpacker with importmapped Hotwire as default the JavaScript setup. This means that a default Rails skeleton will not have to require the full JavaScript toolchain with Webpack by default.

What is rails6 Webpacker?

it is a tool that integrates Webpack with a Rails application. and it provides helpers to use the webpack in our Rails applications. So webpacker simply is the Rails way of using webpack. Now the rails new command will install alot of npm packages via yarn and the webpacker gem will be added to the gemfile by default.


2 Answers

Thanks. That's fine with gem Webpacker 2, but new version of the Gem has a new organisation for files and requires less config.

For Webpack 3, shared.js doesn't seem to be mandatory. Instead, I wrote the config in config/webpack/environment.js like this :

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

const webpack = require('webpack')

// Add an ProvidePlugin
environment.plugins.set('Provide',  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    jquery: 'jquery',
    'window.Tether': "tether",
    Popper: ['popper.js', 'default'],
    ActionCable: 'actioncable',
    Vue: 'vue',
    VueResource: 'vue-resource',
  })
)

const config = environment.toWebpackConfig()

config.resolve.alias = {
  jquery: "jquery/src/jquery",
  vue: "vue/dist/vue.js",
  vue_resource: "vue-resource/dist/vue-resource",
}

// export the updated config
module.exports = environment
like image 66
Kikan Avatar answered Oct 04 '22 16:10

Kikan


Updated for Webpacker 3.5.0 and [email protected]

Popper.js and [email protected] aren't required to install JQuery. However, Bootstrap 4 requires both JQuery and Popper.js, and I assume that is the point of showing them in the original example. Also, I omitted Vue from my example as there is ample documentation on how to add the Vue connections.

To get everything to work, I installed webpack-merge, popper.js, jquery, jquery-ujs, and [email protected] via Yarn.

Once installed, I was able to update ./config/webpack/environment.js with the following code:

/*
  ./config/webpack/environment.js
  Info for this file can be found
  github.com/rails/webpacker/blob/master/docs/webpack.md
*/

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

// Add an additional plugin of your choosing : ProvidePlugin
environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
    $: 'jquery',
    JQuery: 'jquery',
    jquery: 'jquery',
    'window.Tether': "tether",
    Popper: ['popper.js', 'default'], // for Bootstrap 4
  })
)

const envConfig = module.exports = environment
const aliasConfig = module.exports = {
  resolve: {
    alias: {
      jquery: 'jquery/src/jquery'
    }
  }
}

module.exports = merge(envConfig.toWebpackConfig(), aliasConfig)

Now that envConfig.toWebpackConfig() is used in the last statement in environment.js, I needed to change development.js, production.js, test.js to the following:

const environment = require('./environment')

module.exports = environment

Then in ./app/javascript/application.js I added the following:

// ./app/javascript/application.js

/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb

console.log('Hello World from Webpacker')

// JS libraries
import "jquery"
import "jquery-ujs"
import "bootstrap"

To make sure JQuery wasn't being loaded via the asset pipeline, I removed the Rails assets connection in ./app/assets/javascripts/application.js:

// require rails-ujs
// require_tree .

I then added these two lines to the header section in ./app/views/layouts/application.html.haml to display the Webpack content:

= stylesheet_pack_tag 'application'
= javascript_pack_tag 'application' 

After making a static_pages controller and static_pages#index view, after starting the Rails server (rails s), I was able to go to my browser's JS console and run console.log(jQuery().jquery); to see if JQuery was loading. Everything loaded as expected.

Documentation can be found here: https://github.com/rails/webpacker/blob/master/docs/webpack.md

like image 42
sknight Avatar answered Oct 04 '22 17:10

sknight