nuxtlabs / nuxt-component-meta

Gather Nuxt components metadata on build time and make them available on production.
69 stars 6 forks source link

Slot are missing using `defineComponent` #62

Open farnabaz opened 6 months ago

farnabaz commented 6 months ago

Module does not retrieve slots when a component defines with defineComponent or anything beside <script setup lang="ts">

It is strange behavior because for these kinds of components props are fine, but slots are missing.

@stafyniaksacha Do you have an idea about this issue?

For example, when we have this component:

<template>
  <div>
    <h1>Title</h1>
    <p>
      <slot />
    </p>
  </div>
</template>

<script>
import { defineComponent } from 'vue'
export default defineComponent({
  name: 'TextDefine',
  props: {
    title: {
      type: String,
      default: 'Title'
    }
  }
})
</script>

The result will be:

{
    "mode": "all",
    "prefetch": false,
    "preload": false,
    "filePath": "components/TextDefine.vue",
    "pascalName": "TextDefine",
    "kebabName": "text-define",
    "chunkName": "components/text-define",
    "shortPath": "components/TextDefine.vue",
    "export": "default",
    "priority": 1,
    "fullPath": "/Users/far/projects/nuxt/nuxt-component-meta/playground/components/TextDefine.vue",
    "meta": {
      "type": 1,
      "props": [
        {
          "name": "title",
          "global": false,
          "description": "",
          "tags": [],
          "required": false,
          "type": "string | undefined",
          "declarations": [
            {
              "file": "/Users/far/projects/nuxt/nuxt-component-meta/playground/components/TextDefine.vue",
              "range": [
                209,
                266
              ]
            }
          ],
          "schema": {
            "kind": "enum",
            "type": "string | undefined",
            "schema": [
              "undefined",
              "string"
            ]
          },
          "default": "\"Title\""
        }
      ],
      "slots": [],
      "events": [],
      "exposed": [
        {
          "name": "title",
          "type": "string",
          "description": "",
          "declarations": [
            {
              "file": "/Users/far/projects/nuxt/nuxt-component-meta/playground/components/TextDefine.vue",
              "range": [
                209,
                266
              ]
            }
          ],
          "schema": "string"
        }
      ],
      "tokens": []
    }
  }

But with:

<template>
  <div>
    <h1>Title</h1>
    <p>
      <slot />
    </p>
  </div>
</template>

The output is:

{
    "mode": "all",
    "prefetch": false,
    "preload": false,
    "filePath": "components/TextDefine.vue",
    "pascalName": "TextDefine",
    "kebabName": "text-define",
    "chunkName": "components/text-define",
    "shortPath": "components/TextDefine.vue",
    "export": "default",
    "priority": 1,
    "fullPath": "/Users/far/projects/nuxt/nuxt-component-meta/playground/components/TextDefine.vue",
    "meta": {
      "type": 1,
      "props": [],
      "slots": [
        {
          "name": "default",
          "type": "{}",
          "description": "",
          "declarations": [],
          "schema": {
            "kind": "object",
            "type": "{}",
            "schema": {}
          }
        }
      ],
      "events": [],
      "exposed": [
        {
          "name": "$slots",
          "type": "Readonly<InternalSlots> & { default?(_: {}): any; }",
          "description": "",
          "declarations": [
            {
              "file": "/Users/far/projects/nuxt/nuxt-component-meta/node_modules/.pnpm/@vue+runtime-core@3.3.11/node_modules/@vue/runtime-core/dist/runtime-core.d.ts",
              "range": [
                8316,
                8343
              ]
            }
          ],
          "schema": {
            "kind": "object",
            "type": "Readonly<InternalSlots> & { default?(_: {}): any; }",
            "schema": {
              "default": {
                "name": "default",
                "global": false,
                "description": "",
                "tags": [],
                "required": false,
                "type": "((_: {}) => any) | undefined",
                "declarations": [],
                "schema": {
                  "kind": "enum",
                  "type": "((_: {}) => any) | undefined",
                  "schema": [
                    "undefined",
                    {
                      "kind": "event",
                      "type": "(_: {}): any",
                      "schema": []
                    }
                  ]
                }
              }
            }
          }
        }
      ],
      "tokens": []
    }
  }
stafyniaksacha commented 6 months ago

Does it work if you define the slot in defineComponent ? (ref)

<template>
  <div>
    <h1>Title</h1>
    <p>
      <slot />
    </p>
  </div>
</template>

<script lang="ts">
import { defineComponent, type SlotsType } from 'vue'
export default defineComponent({
  name: 'TextDefine',
  slots: Object as SlotsType<{
    default: {}
  }>,
  props: {
    title: {
      type: String,
      default: 'Title'
    }
  }
})
</script>
farnabaz commented 6 months ago

Just tried it and it works 👍 So for defineComponent slots should be defined inside script?