Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sources option to allow loading external component definition #60

Merged
merged 9 commits into from Dec 5, 2023

Conversation

stafyniaksacha
Copy link
Collaborator

@stafyniaksacha stafyniaksacha commented Oct 23, 2023

This PR add a new sources option to allow loading pre-computed component meta file.

export default defineNuxtConfig({
  modules: [
    'nuxt-component-meta',
  ],
  componentMeta: {
    sources: [
      // import from a module
      '@nuxt/ui/component-meta',
      // resolve in project aliases
      '~/meta/library',
      // or directly raw input
      {
        NInput: {
          //...
        },
      }
    ],
  },
})

(This does not cover sources generation, but I have a naive approach here with this)

Copy link
Member

Atinux commented Oct 31, 2023

Thanks for the PR @stafyniaksacha

How do people generate those pre-computed meta file?

Would be nice to add some document to it since it's a bit of a black box from what I try to understand

@stafyniaksacha
Copy link
Collaborator Author

First, I need to talk about the issue.

When using a module living in node_modules, vue-component-meta can't resolve types of exposed components due to .nuxt/tsconfig.json exclude.

This is a basic example:

<script setup lang="ts">
const meta = await useComponentMeta('UButton')
</script>

<template>
  <div>
    <UButton>Button</UButton>
    <!-- props, slots, events, exposed are all empty -->
    <pre>{{ meta.meta }}</pre>
  </div>
</template>

You can find a working version here: https://github.com/stafyniaksacha/nuxt-component-meta-deep-repro

Also, to me, it does not make sense to scan those components each time we start our nuxt app, as they are not likely to change during development.

The solution I've imagined is that when publishing a component library, we can include those pre-computed meta into the package (at the cost of package size, but we can publish to another meta package).

This PR aims to be able to load and merge pre-computed meta into our app, so we can make our useComponentMeta('UButton') working as expected without needing to parse them.

In order to generate the pre-computed meta in our component library, we can't simply add the nuxt-meta-component because it will affect end-users, instead I made a poc for a CLI using citty.
The idea behind is to dynamically register nuxt-component-meta module and do a build. This will generate .nuxt/component-meta.mjs and .nuxt/component-meta.d.ts, we can then either publish them within the package or in another one.

You will find the CLI here: https://github.com/stafyniaksacha/nuxt-meta-component-cli/blob/main/src/main.ts#L33-L75

I think this CLI should be added into this repo if you are ok with the idea.

Then, we can update our component library modules to register those meta if nuxt-component-meta module is detected.

@farnabaz
Copy link
Collaborator

farnabaz commented Nov 6, 2023

Having pre-compiled meta is a good idea to fix typescript exclude issue, and also it will improve performance of development and build.

Having a CLI to generate meta is also a good Idea. Personally, I would like to ship these pre-compiled meta within the components package and not as a different package, therefore I think we might define an output directory for CLI to write generated meta files. This also make it easier for developers to use the CLI and publish meta as separate package.

Additionally, we can create a hook (component-meta:extend) which modules could use it to add/extend components metadata.

Looking forward to seeing the CLI implementation on your PR :)

src/module.ts Outdated
@@ -26,6 +26,7 @@ export default defineNuxtModule<ModuleOptions>({
rootDir: nuxt.options.rootDir,
componentDirs: [],
components: [],
sources: [],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using metaSources might be a better name for this option and will be consistent with metaFields

Also, CLI should generate all metaFields and module can filter them before using them.

@pi0
Copy link
Contributor

pi0 commented Nov 6, 2023

In addtion, we might find a hook in nuxt module builder to precompute this meta after mkdist job to prebundle them 👍🏼 This is a lovely and nice perf enhancement ❤️

@stafyniaksacha
Copy link
Collaborator Author

stafyniaksacha commented Nov 13, 2023

@farnabaz @pi0 The cli is ready for review!

You can use it with:

# build with unbuild
pnpm prepack

# generate meta from playground
./bin/nuxt-component-meta.mjs playground --no-schema

The --no-schema props removes schema information (not types) in the output, to save disk space

There is an issue with the prop type detection into the playground, comment module registration in the nuxt config like:

  modules: [
    '@nuxt/content',
    'pinceau/nuxt',
    // nuxtMetaModule as any
  ],

I think it's due to typescript that can not resolve typing, it's working great when targeting a project that already have older version of this module

bin/nuxt-component-meta.mjs Outdated Show resolved Hide resolved
@stafyniaksacha
Copy link
Collaborator Author

@farnabaz any chance to see it merged?

Copy link
Member

Atinux commented Nov 29, 2023

cc @farnabaz

Copy link
Collaborator

@farnabaz farnabaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for late response.
LGTM ❤️ 🚀

@farnabaz farnabaz merged commit 228c397 into nuxtlabs:main Dec 5, 2023
@stafyniaksacha stafyniaksacha deleted the feat/external-src branch December 5, 2023 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants