vitepress: Build fails due to custom directive missing an SSR Transform

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

<div v-test>test</div>


<script>
export default {
  directives: {
    test: {
      mounted(el, binding) {
        console.log(el)
      }
    }
  }
}
</script>

Expected behavior Build should work even though an SSR implementation for the custom directive doesn’t exist.

System Info

  • vitepress version: 0.6.0
  • vite version: v1.0.0-rc.4
  • Node version: 12.18.3
  • OS version: Catalina 10.15.6

Additional context None.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 22 (9 by maintainers)

Most upvoted comments

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.

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

@mrweiner I don’t think that mutation-observer package supports vue@3

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

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 😅