select2-rails icon indicating copy to clipboard operation
select2-rails copied to clipboard

Rails 6 compatibility / Instructions

Open asecondwill opened this issue 5 years ago • 6 comments

How / Can I use this with Rails 6 and webpacker. Including the scss is fine, but I'm trying to require the js like this in app/javasript/packs/application.js

require("select2")

and get Module not found: Error: Can't resolve 'select2'

asecondwill avatar Nov 08 '19 11:11 asecondwill

I think the answer is, just use yarn & webpacker.

asecondwill avatar Nov 08 '19 12:11 asecondwill

Yeah. You can just install it directly from Yarn and forget about this gem

camiloforero avatar Dec 04 '19 12:12 camiloforero

I'm using Yarn and getting $(...).select2 is not a function. Any clue?

sergiopvilar avatar Dec 17 '19 22:12 sergiopvilar

The issue is jQuery is not being exposed so the select2 plugin cannot be attached

jQuery.fn.select2.amd = S2;

So make sure you load JQuery in # app/config/webpack/environment.js

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

run yarn add expose-loader and then add loader to # app/config/webpack/environment.js

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

timbielawski avatar Dec 24 '19 08:12 timbielawski

If you have the following error:

ERROR in ./node_modules/jquery/dist/jquery.js
Module build failed (from ./node_modules/expose-loader/dist/cjs.js):
ValidationError: Invalid options object. Expose Loader has been initialized using an options object that does not match the API schema.
 - options misses the property 'exposes'. Should be:
   non-empty string | object { globalName, moduleLocalName?, override? } | [non-empty string | object { globalName, moduleLocalName?, override? }, ...] (should not have fewer than 1 item)
    at validate (/Users/marcelo/Code/medimoz/vcp/node_modules/schema-utils/dist/validate.js:96:11)
    at Object.loader (/Users/marcelo/Code/medimoz/vcp/node_modules/expose-loader/dist/index.js:24:28)

replace the expose-loader part of the solution proposed by @timbielawski with this:

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

marcelo-soto avatar Jul 24 '20 03:07 marcelo-soto

I tried including the suggested expose-loader snippets but kept getting another error:

Uncaught Error: Module build failed (from ./node_modules/expose-loader/dist/cjs.js):
TypeError: this.getOptions is not a function
    at Object.loader (.../node_modules/expose-loader/dist/index.js:19:24)
    js application-3e5c803837a6aadd579b.js:11225
    Webpack 5
application-3e5c803837a6aadd579b.js:11225:7
    js application-3e5c803837a6aadd579b.js:11225
    Webpack 5

Uncaught ReferenceError: $ is not defined
    <anonymous> http://localhost:3000/characters/1/edit:127

As a workaround, I found this stackoverflow thread and made the following changes to make select2 work in Rails 6 while no longer needing to install expose-loader:

# application.js

require('jquery') // may be redundant as it is also available in environment.js as a global plugin
require('select2')
window.$ = $
#  app/config/webpack/environment.js

environment.plugins.append('Provide',
 new webpack.ProvidePlugin({
   $: 'jquery',
   jQuery: 'jquery',
   Popper: ['popper.js', 'default']
  })
)

I found that including 'window.jQuery': 'jquery' above would also give me errors.

Also my apologies for the mention of this issue in my repo. Keep forgetting not to document links to other repos.

theIanMilan avatar Sep 26 '21 13:09 theIanMilan