tserkov / vue-scroll-reveal

A Vue directive to wrap @jlmake's excellent ScrollReveal library.
MIT License
164 stars 17 forks source link

Nuxt 3 directive error #40

Open rw-simon opened 2 years ago

rw-simon commented 2 years ago

Hello,

I tried to install this plugin in my Nuxt 3 (rc3) app. I registered the plugin as scroll-reveal.client.ts and added v-scroll-reveal to my html element, but get a Vue warning:

"Failed to resolve directive: scroll-reveal [nitro] [dev] [unhandledRejecton] TypeError: Cannot read properties of undefined (reading 'getSSRProps')"

Is this plugin not yet "adapted" to the new nitro engine or am I doing something wrong?

Thanks for your help, Simon


Plugin:

// /plugins/scroll-reveal.client.ts

import VueScrollReveal from 'vue-scroll-reveal'

export default defineNuxtPlugin(nuxtApp => {
    nuxtApp.vueApp.use(VueScrollReveal)
})

Component: <h1 v-scroll-reveal>Meet the Team.</h1>

Zellement commented 1 year ago

Same issue here

WolfgangDrescher commented 1 year ago

Have a look at https://github.com/nuxt/nuxt.js/issues/13351 and https://github.com/nuxt/nuxt.js/issues/14568. Probably this can be solved by removing .client from the plugin filename (untested).

I got around this by implementing my own v-scroll-reveal directive. Have a look at index.js for inspiration and import directly from the scrollreveal package.

tserkov commented 1 year ago

Sorry for the delay all! I've just pushed vue-scroll-reveal@2.0.0, which is intended for Vue/Nuxt 3 (1.x.x only supports Vue/Nuxt 2).

The issue here was harder to debug than I'd imagined, and in the end came down to the filename -- rather than plugins/scroll-reveal.client.ts, the filename needed to be camelCase plugins/scrollReveal.client.ts, likely due to the auto-importer's logic.

Please let me know if this does/does not work for you! If it all goes well, I'll officially publish to NPM on Saturday (31 September)!

WolfgangDrescher commented 1 year ago

It is interesting that this depends on the filename. In the nuxt 3 docs they even make an example with a kebab case plugin name: plugins/vue-gtag.client.js (see the docs here).

Does there speak anything against registering this plugin with nuxtApp.vueApp.use(VueScrollReveal, defaultOptions) like in the previous version? I liked the possibility to add default settings.

I suggest adding a default export with a custom vue plugin:

export default {
  install: (app, options) => {
    app.directive('scroll-reveal', vScrollReveal);
  },
};

Probably this will need a generator function createScrollRevealDirective(defaultOptions) or similar to pass default options as a parameter. If you want, I can make a pull request.

Also note that I had problems when using this plugin in combination with nuxt page transitions:

.page-leave-active,
.page-enter-active {
    transform: translateY(0);
    transition: all 0.3s;
}
.page-enter-from,
.page-leave-to {
    opacity: 0;
    transform: translateY(-15px);
}

This is probably not an issue of this plugin but I could only get this work by adding a timeout of the duration of the page transition. Without this timeout ScrollReveal was always bugged (some elements were hidden with visibility: none) and not working without a hard refresh of the page.

Zellement commented 1 year ago

@tserkov Hello!

Thanks for working on this!

Not sure if I am doing something wrong here, but....

npm install --save vue-scroll-reveal@2 scrollreveal
npm ERR! code ETARGET
npm ERR! notarget No matching version found for vue-scroll-reveal@2.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

Deleted node_modules and package-lock.json

Any ideas?

WolfgangDrescher commented 1 year ago

https://www.npmjs.com/package/vue-scroll-reveal?activeTab=versions Version 2 is not yet released on npm.

Zellement commented 1 year ago

@WolfgangDrescher Good point! He literally said he'd publish to NPM this week haha, silly me.

Any suggestions how to test this out without using NPM?

WolfgangDrescher commented 1 year ago

Probably like this: clone repository, checkout v2 branch, npm link, cd into your project and use npm link vue-scroll-reveal. Alternatively you can try this: npm i https://github.com/tserkov/vue-scroll-reveal/tree/v2.

tserkov commented 1 year ago

It is interesting that this depends on the filename. In the nuxt 3 docs they even make an example with a kebab case plugin name: plugins/vue-gtag.client.js (see the docs here).

That is interesting! My best guess is that a path or name normalizer (isn't the culprit always regex?) is being inconsistently applied for auto-discovered plugins for the each client/server/global mode.

Does there speak anything against registering this plugin with nuxtApp.vueApp.use(VueScrollReveal, defaultOptions) like in the previous version? I liked the possibility to add default settings.

I suggest adding a default export with a custom vue plugin:

export default {
  install: (app, options) => {
    app.directive('scroll-reveal', vScrollReveal);
  },
};

Probably this will need a generator function createScrollRevealDirective(defaultOptions) or similar to pass default options as a parameter. If you want, I can make a pull request.

Glad to hear that feature is in demand! I've implemented it as createScrollRevealDirective, which returns a directive -- no need to much around with plugins. 😄

README and version updated to match (v2.1.0)-- let me know how it works for you!

Also note that I had problems when using this plugin in combination with nuxt page transitions:

.page-leave-active,
.page-enter-active {
  transform: translateY(0);
  transition: all 0.3s;
}
.page-enter-from,
.page-leave-to {
  opacity: 0;
  transform: translateY(-15px);
}

This is probably not an issue of this plugin but I could only get this work by adding a timeout of the duration of the page transition. Without this timeout ScrollReveal was always bugged (some elements were hidden with visibility: none) and not working without a hard refresh of the page.

If you get some time, I know you mentioned you ran a custom local ScrollReveal directive; if it happens with that version too, then it's likely a Nuxt+ScrollReveal limitation. If so, I imagine your comment in this issue should help anyone who bumps into the buginess future.

WolfgangDrescher commented 1 year ago

That is interesting! My best guess is that a path or name normalizer (isn't the culprit always regex?) is being inconsistently applied for auto-discovered plugins for the each client/server/global mode.

Could be, but I haven't looked into it too much. I don't know if this is already a known issue in nuxt 3. Maybe it's worth opening an issue in their repository for this?

Glad to hear that feature is in demand! I've implemented it as createScrollRevealDirective, which returns a directive -- no need to much around with plugins. 😄

Nice solution, thank you. You can even clean this up a bit like this:

export const vScrollReveal = createScrollRevealDirective({});

If you get some time, I know you mentioned you ran a custom local ScrollReveal directive; if it happens with that version too, then it's likely a Nuxt+ScrollReveal limitation. If so, I imagine your comment in this issue should help anyone who bumps into the buginess future.

I just tested your new changes. Still the same buggy behaviour without a timeout of the duration of the page transition. So anyone who runs into this problem has to create a custom directive anyway. Or do you think it is worth implementing this into this plugin. I don't think so. I really just did this:

// wait for page transition to end
setTimeout(() => {
    reveal(el, value, modifiers);
}, 320);

We could add this by adding an additional parameter to the createScrollRevealDirective(defaultOptions, timeoutDuration = 0) function. But this seems wrong. Let's better wait until the final release of nuxt 3 and see if this is still an issue.

Zellement commented 1 year ago

I've given this a go, but unfortunately can't get it working with either of @WolfgangDrescher's approaches.

Using npm i https://github.com/tserkov/vue-scroll-reveal/tree/v2 got me the furthest, and using the updated guide from https://github.com/tserkov/vue-scroll-reveal/tree/v2, gives me the following:

[Vue warn]: Failed to resolve directive: scroll-reveal
[nuxt] [request error] [unhandled] [500] Cannot read properties of undefined (reading 'getSSRProps')

The file is named scrollReveal.client.ts inside my plugins directory, using the following:

import { createScrollRevealDirective } from 'vue-scroll-reveal' // OR if using custom default options

export default defineNuxtPlugin((nuxtApp) => {
    // OR if using custom default options
    nuxtApp.vueApp.directive('scroll-reveal', createScrollRevealDirective({
        delay: 1000,
        duration: 150,
        reset: true
    }))
})

Additionally, deleted node_modules and installed scrollreveal as well.

Not sure if I'm doing something wrong here?

WolfgangDrescher commented 1 year ago

I'm also not entirely sure about this problem. I did also get this error several times with other plugins. You can try to remove .client from the filename. Have a look at these resources:

https://github.com/rigor789/vue-scrollto/pull/715/files https://vuejs.org/guide/scaling-up/ssr.html#custom-directives https://github.com/nuxt/nuxt.js/issues/13351 https://github.com/nuxt/nuxt.js/issues/14568

WolfgangDrescher commented 1 year ago

It seems like v2 is not yet released on npm: https://www.npmjs.com/package/vue-scroll-reveal?activeTab=versions

tserkov commented 1 year ago

Thanks, I've just published it! 🙈