KingSora / OverlayScrollbars

A javascript scrollbar plugin that hides the native scrollbars, provides custom styleable overlay scrollbars, and preserves the native functionality and feel.
https://kingsora.github.io/OverlayScrollbars
MIT License
3.71k stars 215 forks source link

overlayscrollbars svelte webpack: Cannot read properties of undefined (reading '$$') #610

Closed Wiblz closed 5 months ago

Wiblz commented 5 months ago

Describe the bug Getting "Cannot read properties of undefined (reading '$$')" in overlayscrollbars-svelte.mjs:281 when trying to use the most basic example of overlayscrollbars-svelte in a webpack setup.

To Reproduce Here's a minimized setup of my project: stackblitz I can feel that my webpack setup is a bit scuffed, so it could be that.

KingSora commented 5 months ago

Good day @Wiblz :)

I'm not too familiar of how webpack handles svelte bundles... I'll check it out as soon as I have time :)

KingSora commented 5 months ago

@Wiblz Please try to specify conditionNames: ['svelte', 'browser', 'import', 'require', 'node'], in the resolve object.. so the final resolve config looks like this:

  resolve: {
    alias: {
      svelte: path.resolve('node_modules', 'svelte/src/runtime'),
    },
    extensions: ['.mjs', '.js', '.svelte'],
    mainFields: ['svelte', 'browser', 'module', 'main'],
    conditionNames: ['svelte', 'browser', 'import', 'require', 'node'],
  },
KingSora commented 5 months ago

Short explanation why it wasn't working:

Svelte has its own build logic and tries whenever to load the original .svelte components. Those should be in the package. These original .svelte components are declared in the package.json in the "svelte" field or in the "svelte" export condition field. If the bundler of your choice can resolve the those fields correctly, you'll end up with the "original" .svelte component and your app should compile correctly.

Then there is also a second possibility for library authors to also provide a pre-compiled version of the component as a plain .js file. In overlayscrollbars case its the .mjs, .cjs, esm.js and .cjs.js files. As already mentioned those are pre-compiled and should be used with the new Component() API. (https://github.com/sveltejs/svelte/issues/6584#issuecomment-1146961850)

The problem here was that webpack resolved the overlayscrollbars package to its .mjs component (pre-compiled) and you initialized the component in the declarative way like <OverlayScrollbarsComponent> but this is not guaranteed to work if the version the component was pre-compiled with is not the version you are using. (https://github.com/sveltejs/svelte/issues/6584#issuecomment-1019578529)

With adding the conditionNames webpack will resolve correctly to the original .svelte component and thus the declarative way should work again.

Also Related: https://github.com/sveltejs/svelte/pull/8295, https://github.com/sveltejs/svelte-loader

Wiblz commented 5 months ago

@KingSora Thank you for a prompt response. I think I understand your explanation of why it wasn't working at least on a conceptual level. Unfortunately because my lack of knowledge of front end build tools and webpack specifically I can't fully understand how adding conditionNames affects the described issue.

I attempted the proposed solution but it broke my build with 40+ errors coming from other dependencies. I then tried setting conditionNames to different subsets of given values (again, completely oblivious of what I was actually changing) and found that some of them resulted in a successful build. In the end, I settled with ['svelte', 'browser', 'import'] as described in svelte-loader docs.

KingSora commented 5 months ago

@Wiblz I'm glad you found a solution! :) Can I consider the issue as fixed?

Wiblz commented 5 months ago

@KingSora Yeah, sure.