-->

Rails 6: How to add jquery-ui through webpacker?

2020-03-23 17:08发布

问题:

I'm currently trying to implement a datepicker into my application, the problem is that there is no documentation on how to add the jquery-ui-rails gem through webpacker.

Probably there is another way to add gems or another gem that would fit my needs?

回答1:

You no longer need to add javascript libraries as gems (which are managed by the bundler). Instead, you add them with yarn and they are managed by webpack (which is enabled by adding the webpacker gem to the Gemfile).

The following steps worked for me to get jquery-ui working in Rails 6:

  1. On the terminal, inside your application type:
yarn add jquery-ui-dist
  1. Your config/webpack/environment.js needs to look as follows:
const { environment } = require('@rails/webpacker')

const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery'
  })
);

const aliasConfig = {
    'jquery': 'jquery-ui-dist/external/jquery/jquery.js',
    'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
};

environment.config.set('resolve.alias', aliasConfig);

module.exports = environment
  1. Restart your rails server

  2. In the application.html.erb, include the jquery-ui theme:

<!DOCTYPE html>
<html>
  <head>
    <title>Jquery UI Test</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>

    <%= stylesheet_link_tag '//ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/le-frog/jquery-ui.min.css' %>

    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
  1. Now, in your app/javascript/packs/application.js, you can use jquery-ui:
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

require("jquery") // Don't really need to require this...
require("jquery-ui")

$(function(){
    // Plain jquery
    $('#fadeMe').fadeOut(5000);

    // jquery-ui
    const availableCities = ['Baltimore', 'New York'];
    $('#cityField').autocomplete( { source: availableCities } );
    $('#calendarField').datepicker( { dateFormat: 'yy-mm-dd' } );
})

This will work for a page that looks as follows:

<div id='fadeMe'>Fade me</div>

City: <input type='text' id='cityField' />
Calendar: <input type='text' id='calendarField' />


回答2:

None of these answers quite worked for me. Here's how I ended up getting it implemented:

yarn add jquery

then

yarn add jquery-ui-dist

in your app/javascript/packs/application.js file:

// jquery
import $ from 'jquery';

global.$ = $
global.jQuery = $


require('jquery-ui');

// jquery-ui theme
require.context('file-loader?name=[path][name].[ext]&context=node_modules/jquery-ui-dist!jquery-ui-dist', true,    /jquery-ui\.css/ );
require.context('file-loader?name=[path][name].[ext]&context=node_modules/jquery-ui-dist!jquery-ui-dist', true,    /jquery-ui\.theme\.css/ );

and in config/webpack/environment.js:

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

const webpack = require('webpack');


// resolve-url-loader must be used before sass-loader
environment.loaders.get('sass').use.splice(-1, 0, {
    loader: 'resolve-url-loader',
    options: {
        attempts: 1
    }
});


// 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 aliasConfig = {
    'jquery': 'jquery/src/jquery',
    'jquery-ui': 'jquery-ui-dist/jquery-ui.js'

};

environment.config.set('resolve.alias', aliasConfig);

//
module.exports = environment;

A restart to my server got it working fine for me. Here is a link with details on webpacker that I used to get this to work:

https://gist.github.com/maxivak/2612fa987b9f9ed7cb53a88fcba247b3#jquery-jquery-ui



回答3:

Kalman's answer puts jQuery within the scope of the scripts in the app/javascript directory but not with any in-line javascript that you may have on your webpages.

If you want to access jQuery from the scope of the webpage, you could can put jQuery under the public directory then modify app/views/layouts/application.html.erb to link to it like this:

<!DOCTYPE html>
<html>
  <head>
    <title>JqueryTest</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>


    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <script src="/jquery-3.4.1.js"></script>
    <%= stylesheet_link_tag "/jquery-ui-1.12.1.custom/jquery-ui.min.css" %>
    <script src="/jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>


  </head>

  <body>
    <%= yield %>
  </body>
</html>