1

In my Rails 6.x app, I was using Webpacker in order to compile my styles and transpile my JS.

As part of my apps upgrade to Rails 7, I scrapped Webpacker (as it's no longer recommended) and switched over to the new cssbundling-rails and jsbundling-rails gems.

These are super fast and sooo much easier to use.

However, I just ran a Lighthouse report on my site and I think certain pages on my site are loading all my JS even though a lot of it is not even executed on most pages.

For example I have a script that plays audio using the Plyr library on one page.

My script for this, at the top has an import like:

import Plyr from 'plyr'

I've tried to conditionalism this by checking if a specific element exists on the page first before importing but it didn't like that.

How can I only perform some of these imports when they are necessary and not when they are not.

How do I convert the above to be conditional?

Thanks, Neil

UPDATE:

My updated script:

if (document.querySelector('audio')) {
    let audio = document.querySelector('audio');
    import('plyr').then(Plyr => {
        const player = new Plyr(audio, {
            'controls' : ['play'],
            'autoplay' : false
        })
    });
}

The error i'm getting is:

Uncaught (in promise) TypeError: Plyr2 is not a constructor.

How can I access the Plyr object?

rctneil
  • 7,016
  • 10
  • 40
  • 83

1 Answers1

2

Instead of using import Plyr from 'plyr', you can use dynamic import of import('plyr') which you can use anywhere, including conditional logic. Keep in mind, dynamic imports return promises. So async/await So,

if(somevalue === true){
   import('plyr').then(resp => doSomething)
}
  • Hi @issayah, Thanks for the answer. I've updated my code in my OP. I'm getting some errors and not too sure why? Could you please take a look? – rctneil Feb 08 '22 at 10:59
  • @rctneil: Do a `console.log(Plyr)` to see what it is. The value will be an object with a `default` property and a property for every named export. – Felix Kling Feb 08 '22 at 12:25
  • @FelixKling Hi! The output of that is https://dropover.cloud/a6030d – rctneil Feb 08 '22 at 12:46
  • A console log would be interesting. Or taking a look at what the plyr package is exporting. I'm not sure why it's doing that, beyond just using the wrong exported function. –  Feb 08 '22 at 14:03
  • @Issayah The console.log is shown in the image linked to in my previous comment. – rctneil Feb 08 '22 at 14:27
  • Oh. It's still early lmao. Try using Plyr.default. I think it's wrapped in the import function –  Feb 08 '22 at 14:42
  • That worked. Why do I need to use .default on it? While testing, I tried this dynamic import on another module elsewhere and it's having the same issue. Do I really need to add .default after the module name in the .then each time i use it? Can I do it up the top globally somehow? – rctneil Feb 08 '22 at 14:59
  • Regular imports import the data directly, whereas dynamic import returns a module object, rather than the data. If it wasn't that way, there would be no ability to differentiate between exported data, and an exported default. It's just how it works. I think of it the same as fetching data using axios. Pretty much always gotta do .data to get the useful stuff. –  Feb 08 '22 at 16:32