Closed VinceG closed 1 year ago
Hi could you elaborate a bit more on this use case? Why would you paste such code into md file?
@kiaking Of Course. I have the following component written in Vue 3 https://github.com/VinceG/vue-click-away
As part of the component i wrote the documentation in vitepress, if you look at the Gif you'll see the example usage and demo within vitepress. I am trying to deploy it into gh-pages (or anything else really) and while running the production build it fails with the above error message.
The markdown file for the demo looks like this:
https://raw.githubusercontent.com/VinceG/vue-click-away/master/docs/index.md
But the actual code that is failing is located here: https://github.com/VinceG/vue-click-away/blob/master/index.js
I don't think the markdown file has anything to do with it, vitepress is not able to build for production when there are directives in the codebase. I gave a simple reproduction case above to replicate this issue with a new vitepress setup.
I hope this helps.
EDIT: in Vuepress we have
Oh I see. I haven't checked, but does VuePress support this feature...!? I think you should register that component, and then use it inside the markdown.
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/dist/client/theme-default'
import VueClickAwayExample from './components/VueClickAwayExample.vue'
export default {
...DefaultTheme,
enhanceApp({ app }) {
app.component('VueClickAwayExample', VueClickAwayExample)
}
}
<!-- index.md -->
# Vue Click Away
<VueClickAwayExample />
@kiaking Hmm, well using it isn't the problem. it's building for production. once i run yarn build
it throws the above error
Thanks for the answer! I've confirmed. Yap, it is failing on build time due to the error you described.
I'm not too familiar with the SSR with directives so I have to learn things before we can fix this 😅
This is not really a bug, since you do need to provide the corresponding directive transforms to ensure you are rendering correct HTML during SSR. However some directives like click away don't really render any props, so it makes sense to change this to a warning instead of an error in @vue/compiler-ssr
.
That said, a client only wrapper component is fairly simple:
import { ref, onMounted } from 'vue'
const ClientOnly = {
setup(_, { slots }) {
const show = ref(false)
onMounted(() => { show.value = true })
return () => show.value && slots.default ? slots.default() : null
}
}
This is not really a bug, since you do need to provide the corresponding directive transforms to ensure you are rendering correct HTML during SSR. However some directives like click away don't really render any props, so it makes sense to change this to a warning instead of an error in
@vue/compiler-ssr
.That said, a client only wrapper component is fairly simple:
import { ref, onMounted } from 'vue' const ClientOnly = { setup(_, { slots }) { const show = ref(false) onMounted(() => { show.value = true }) return () => show.value && slots.default ? slots.default() : null } }
@yyx990803 thank you. Any idea how to write those directive transforms? I wasn’t able to find any documentation regarding this.
Also, are there plans to add client only component for vitepress like the equivalent in vuepress?
v3 SSR docs are not fully complete yet, so for now you'll have to read the types here: https://github.com/vuejs/vue-next/blob/master/packages/compiler-core/src/transform.ts#L56
ClientOnly is implemented in 8809d2d and will be available in the next release.
OK cool, since ClientOnly
component is here, maybe we should just document to use it when you have component that uses directive
option.
If anyone lands here by looking on how to update his directive to make it SSR compatible (which is my case), I advise you to take a look at the native directives code from vue-next repository.
Starting at v-show, which is here: https://github.com/vuejs/vue-next/blob/master/packages/runtime-dom/src/directives/vShow.ts
Update:
Even after implementing the getSSRProps on my own directive, I can't get the directive to work with VitePress.
I still get the Custom directive is missing corresponding SSR transform and will be ignored.
error.
The same happens when wrapping my directive with a <ClientOnly />
component, which makes me think this might be a bug ?
Even when trying to add an absolute return value in the getSSRProps hook, Vitepress does not seem to handle it.
I tried it this way, so I could debug when the hook is called, and it doesn't seem to be the case.
getSSRProps({ value }) {
return { style: { backgroundColor: 'blue' }Â }
}
Maybe this is a wrong implementation on my side, but I think this is closely related to this issue.
If you want me to open another issue for this discussion, please let me know.
Otherwise we might want to switch this back to a bug
because the <ClientOnly />
workaround should stay a workaround and not the encouraged method to fix this when you have access to the directive code.
Update:
Even after implementing the getSSRProps on my own directive, I can't get the directive to work with VitePress.
I still get the
Custom directive is missing corresponding SSR transform and will be ignored.
error.The same happens when wrapping my directive with a
<ClientOnly />
component, which makes me think this might be a bug ?Even when trying to add an absolute return value in the getSSRProps hook, Vitepress does not seem to handle it.
I tried it this way, so I could debug when the hook is called, and it doesn't seem to be the case.
getSSRProps({ value }) { return { style: { backgroundColor: 'blue' }Â } }
Maybe this is a wrong implementation on my side, but I think this is closely related to this issue.
If you want me to open another issue for this discussion, please let me know.
Otherwise we might want to switch this back to a
bug
because the<ClientOnly />
workaround should stay a workaround and not the encouraged method to fix this when you have access to the directive code.
Because there should be a directive transforms
.
According to this, I find the way to provide the directive transforms
to resolve this error.
We can pass directiveTransforms
option via vue-loader.
// webpack config
module.exports = {
module: {
// ...
rules: [
{
test: /\.vue$/,
use: [
{
loader: "vue-loader",
options: {
compilerOptions: {
directiveTransforms: {
// <div v-custom-directive />
"custom-directive": () => ({
props: [],
}),
},
},
},
},
],
},
// ...
],
},
plugins: [new VueLoaderPlugin()],
};
Or pass it via compile
function.
import { compile } from "@vue/compiler-dom";
const { code } = compile(`<p v-custom-directive></p>`, {
// ...
directiveTransforms: {
"custom-directive": () => ({
props: [],
}),
},
});
I got the same error when I use renderToString
of @vue/server-renderer
with a custom directive and I am not familiar with vitepress
.
Hope this helps you. @Tahul
I don't know what I am doing wrong but using the ClientOnly don't fix the build problem for me. I had to remove all custom directives for it to build
A temporary fix:
A temporary fix:
thanks @antfu It worked... It was a mistake I made that prevent it from working before.
I cant understand how vue directives works in VUE 3 . It has 3 weeks that I am trying a solution for that . @yyx990803 help us =),
I didn't found a documentation about that . A SPA DIRECTIVE IS LIKE THAT -
app.directive('color', {
mounted (el, binding) {
el.style.color = 'purple'
}
})
HOW COULD I DO IT IN SSR ? -
export default (dir) => {
return {
props: []
}
}
I don't understand how can I access this props
A temporary fix:
thank you fixed. I hope there is a permanent solution.
This is still an annoying bug. For reference, this is a bug in vuepress@2.0.0-beta.27
as well, which isn't the latest version at time of posting this, but is definitely newer than these comments and original post here. As in a lot of front end development, we have to install a separate patch package as a workaround, which is great, but is not ideal.
Is this issue going to be fixed or on the roadmap at all?
This is not reproducible in VitePress alpha with the below code:
# Hello World
<div v-test>test</div>
<script setup>
const vTest = {
mounted: (el) => {
console.log(el)
}
}
</script>
I am closing this issue for now. If you think that there is still an issue, please let us know.
I'm aware that this is closed, but does https://github.com/vueuse/patch-vue-directive-ssr still work for anybody? I've run into this error a few times with userland packages (such as https://github.com/PNKBizz/vue-mutation-observer) and it doesn't seem to help.
@mrweiner I don't think that mutation-observer package supports vue@3
Describe the bug
Adding a simple directive inside a markdown file or an SFC throws an error during the build. Seems like ClientOnly component does not exist yet in VitePress.
Custom directive is missing corresponding SSR transform and will be ignored.
To Reproduce
Expected behavior Build should work even though an SSR implementation for the custom directive doesn't exist.
System Info
Additional context None.