2

I'm really struggling with this all new JS changes to Rails. I'm trying to implement stupidly simple slider script, Glide.js

This is my app/javascripts/packs/front.js file:

// Internal
// require("@rails/ujs")
import Glide from '@glidejs/glide'
console.log(Glide);

import Rails from '@rails/ujs'
Rails.start()
require('jquery')
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

// Custom

require('./vendor_js/vendor_import.js')

Here is a file where I do call gilder (new_slider.js):

// require("./slider.js");
require("./new_slider.js");

require("./mBox.js");
require("./lightbox_script.js");
require("./map.js");
// import lightbox from "packs/custom/lightbox_script.js";

Here is the new_slider.js file:

$(document).on('turbolinks:load', function(){
  console.log("new_slider.js is loaded");
  var slider = document.querySelector('.glide');

  if (slider) {
    var glide = new Glide(slider);
    console.log("glide is loaded:");
    console.log(glide);
    glide.mount();
  }

});

This is my haml view:

.glide
  .glide__track{"data-glide-el" => "track"}
    %ul.glide__slides
      %li.glide__slide
        %img{:src => asset_path('slider/winter_holidays/1.jpg'), :style => "width:100%"}/
      %li.glide__slide
        %img{:src => asset_path('slider/winter_holidays/2.jpg'), :style => "width:100%"}/
      %li.glide__slide
        %img{:src => asset_path('slider/winter_holidays/3.jpg'), :style => "width:100%"}/

  %div{"data-glide-el" => "controls"}
    %button{"data-glide-dir" => "<<"} start
    %button{"data-glide-dir" => ">>"} end

And this is my console output:

ƒ Glide$$1() {
    classCallCheck(this, Glide$$1);
    return possibleConstructorReturn(this, (Glide$$1.__proto__ || Object.getPrototypeOf(Glide$$1)).apply(this, arguments));
  }
new_slider.js:2 new_slider.js is loaded
new_slider.js:6 Uncaught ReferenceError: Glide is not defined
    at HTMLDocument.<anonymous> (new_slider.js:6)
    at HTMLDocument.dispatch (event.js:328)
    at HTMLDocument.elemData.handle (event.js:148)
    at Object../node_modules/turbolinks/dist/turbolinks.js.e.dispatch (turbolinks.js:75)
    at r.notifyApplicationAfterPageLoad (turbolinks.js:994)
    at r.pageLoaded (turbolinks.js:948)
    at turbolinks.js:872

Gilde is obviously loaded since console.log(Glide) provides an output. new_slider.js file is loaded after importing Gilde, so there can't be any conflict. The only issue I found so far was this one, but unfortunately it doesn't help at all.

Could someone point me in the right direction?

leonheess
  • 16,068
  • 14
  • 77
  • 112
mohnstrudel
  • 639
  • 8
  • 22
  • Vote on [this proposal](https://meta.stackoverflow.com/questions/354583/disentangle-the-yarn) to ease the tag confusion. – leonheess Feb 10 '20 at 12:27

2 Answers2

1

Try loading jquery as a global plug-in:

# config/webpack/environment.js

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

const webpack = require('webpack');

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

module.exports = environment

And then remove require("jquery") from application.js

Dijkie85
  • 1,036
  • 8
  • 21
  • Doesn't work, unfortunately, my `environment.js` looked as following: `const { environment } = require('@rails/webpacker') const webpack = require('webpack') environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ $: 'jquery/src/jquery', jQuery: 'jquery/src/jquery' }) ) module.exports = environment` I've commented `require("jquery")` out, changed `prepend` to `append`, changed `jquery/src/jquery` to simple `jquery` it does not help at all :-( – mohnstrudel Nov 19 '19 at 13:05
  • Although @rossta's answer was the correct one to solve my problem, I remember having the same issue with jquery not being available globally. Would like to upvote your answer ´, so maybe a future reader with the same problem can check both options. – mohnstrudel Nov 20 '19 at 12:36
1

In Webpack-land, you'll typically need to import a given module explicitly in every file where you want to use it. So, even though you imported Glide in app/javascripts/packs/front.js, if you want to reference it in new_slider.js, you'll need to import it there as well:

// new_slider.js
import Glide from '@glidejs/glide';

// ...
rossta
  • 11,394
  • 1
  • 43
  • 47
  • Holy molly, that was it! Never in my life I would've thought about it... Thanks a thousand times. But why is that this way? I mean front.js is just a collector for all other JS, meaning that upon loading any page, `front.js` should be already loaded in my case. – mohnstrudel Nov 20 '19 at 12:34
  • 1
    Webpack is a module bundler—every file is treated as module with its own scope. Imports and exports are how to get modules to "talk" to each other. Here's a resource to learn more about ES6 modules, which is typically the type of module you'd be using with Webpacker: https://exploringjs.com/es6/ch_modules.html – rossta Nov 20 '19 at 18:36