Vite vuetify plugin doesn’t load components listed in external libraries

Issue

This Content is from Stack Overflow. Question asked by Sasank M

I am creating a library that wraps Vuetify 3 components. But when I try to use the library it gives the following error:
[Vue warn]: Failed to resolve component: v-btn If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.

Library vite.config.ts :

import { fileURLToPath, URL } from 'node:url';
import { resolve } from 'node:path';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import vuetify from 'vite-plugin-vuetify';

export default defineConfig({
  plugins: [
    vue(),
    vueJsx(),
    // vuetify({ autoImport: true, styles: 'none' }), // Don't export vuetify
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
  build: {
    lib: {
      entry: resolve(__dirname, 'src/main.ts'),
      name: '@my/ui',
      // the proper extensions will be added
      fileName: 'my-ui',
    },
    rollupOptions: {
      // make sure to externalize deps that shouldn't be bundled
      // into your library
      external: ['vue', 'vuetify'],
      output: {
        // Provide global variables to use in the UMD build
        // for externalized deps
        globals: {
          vue: 'Vue',
          vuetify: 'Vuetify',
        },
      },
    },
  },
});

Nuxt project nuxt.config.ts:

import { defineNuxtConfig } from 'nuxt';
import vuetify from 'vite-plugin-vuetify';

export default defineNuxtConfig({
  css: ['@/assets/css/main.css'],
  modules: [
    async (options, nuxt) => {
      nuxt.hooks.hook('vite:extendConfig', (config) =>
        config.plugins.push(vuetify({ autoImport: true }))
      );
    },
  ],
  build: {
    transpile: ['@my/ui', 'vuetify'],
  },
});

Nuxt project app.vue:

<template>
 <v-app>
   <v-main>
     <HelloWorld label="Test" primary />
   </v-main>
 </v-app>
</template>

<script lang="ts" setup>
import { HelloWorld } from '@my/ui';
</script>

Nuxt project plugin vuetify.ts:

import 'vuetify/styles';
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';

export default defineNuxtPlugin((nuxtApp) => {
  const vuetify = createVuetify({
    // components, if imported components getting resolved but treeshaking doesn't work. 
    // directives
  });
  nuxtApp.vueApp.use(vuetify);
});

Expected Behavior

Vuetify components from the Library project should be auto imported.

Current workaround:

If the vuetify components are imported in the parent project then the components are resolved. But this causes issue as the library users has to know what to import or import on global which is creating larger bundle size.

Is there an alternative way to implement and meet the following criteria:

  • Wrapping module doesn’t depend on vuetify (Peer dep only)
  • Consuming app can auto import and get all of the benefits of tree shaking
  • Consuming app doesn’t need to import any of the peer dependencies of the wrapping module.

Thank you so much in advance.



Solution

This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?