primefaces / primevue

Next Generation Vue UI Component Library
https://primevue.org
MIT License
10.51k stars 1.23k forks source link

Create default export for all Vue components #614

Closed gwenf closed 3 years ago

gwenf commented 4 years ago

Current Behavior:

You have to import components separately:

import Button from '...'
import Card from '...'

app.component('Button', Button)
app.component('Card', Card)

Desired Behavior:

There should be index.js and index.ts files in the root folder for components so we can use this syntax:

import { Button, Card } from '...'

app.component('Button', Button)
app.component('Card', Card)
cagataycivici commented 3 years ago

We've done it for PrimeNG but then the whole suite gets imported to your app, which is not desired for bundle size. Instead you can create your own your-primevue-shorthand.js file and import-export the components from there to end up with;

import { Button, Card } from 'your-primevue-shorthand';
mariusa commented 3 years ago

For apps which do want to use most components and bundle size isn't an issue, is there a way to quickly setup all of them?

In vue 2 with bootstrap-vue, this worked:

import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue)

Then all components were available in the entire app.

tageecc commented 3 years ago

For apps which do want to use most components and bundle size isn't an issue, is there a way to quickly setup all of them?

In vue 2 with bootstrap-vue, this worked:

import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue)

Then all components were available in the entire app.

any updates?

epcgrs commented 2 years ago

For apps which do want to use most components and bundle size isn't an issue, is there a way to quickly setup all of them?

In vue 2 with bootstrap-vue, this worked:

import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue)

Then all components were available in the entire app.

In vue3 this not working, bootstrap-vue is only supported by v2 🙁

promiseoomos commented 2 years ago

Why do you have to import all the components seperately? It will make your code cumbersome. Please you guys should work it out. Thanks

xzdwq commented 1 year ago

There is a way with a plugin for vite. It works for me

  "unplugin-vue-components": "^0.22.7"
  "vite": "^3.2.1",
  "vue": "^3.2.41",
  "primevue": "^3.23.0",
  "primeicons": "^6.0.1",

vite.config.ts

import Components from 'unplugin-vue-components/vite';

export default defineConfig({
  plugins: [
    Components({
      extensions: ['vue'],
      include: [/\.vue$/, /\.vue\?vue/],
      dts: 'src/components.d.ts',
      dirs: ['src/**/*', 'node_modules/primevue/**/*'],
    }),
  ],
});

app.vue

<template>
  <div>
    <Toolbar>
      <template #end>
        <Button icon="pi pi-search" class="mr-2" />
      </template>
    </Toolbar>
  </div>
</template>

<script setup lang="ts">
// import Toolbar from 'primevue/toolbar';
// import Button from 'primevue/button';
</script>
2000sh commented 1 year ago

The solution above worked for me.

JoaoHamerski commented 1 year ago

I figure out this solution to import all components, if anyone want to use:

I created a new file primevue.js to keep all my primevue related configs (that's for vite):

import PrimeVue from 'primevue/config'

const components = import.meta.glob(
  [
     /**
     * Import all components from primevue node_modules
     **/
    '/node_modules/primevue/*/*.vue',
     /** 
     * If you won't use Editor (quill.js) or Chart (chart.js) add it here
     * or it'll throw an error looking for these libraries.
     **/
    `!**/(Editor|Chart).vue` 
  ],
  { eager: true }
)

export const primeVueConfig = (vueInstance) => {
  Object.entries(components).forEach(([path, definition]) => {
    const componentPath = path.split('/')
    const componentName = componentPath.pop().replace(/\.\w+$/, '')
    const folderName = componentPath.pop()

    /**
    * This verification is important, because there are multiple folders 
    * with the same component name ending with ".vue", 
    * so it's important we check if our code is only importing the main component
    **/ 
    if (folderName.toLowerCase() === componentName.toLowerCase()) {
      vueInstance.component(componentName, definition.default)
    }
  })

  vueInstance.use(PrimeVue)
}

Just use this function:

// vue related imports...
import { primeVueConfig } from './primevue'

const app = createApp(App)

primeVueConfig(app)

You can edit this code as you need, for example add more exceptions on imports if you don't want to import everything.

Also I suggest to add a prefix to the component name like so:

// Every PrimeVue component will start with "P", "PButton" instead of "Button" 
vueInstance.component(`P${componentName}`, definition.default)
factoidforrest commented 10 months ago

While the above Vite workaround does work, I'm concerned that this opinionated approach is inconvenient for those who do not need to hyperoptimize bundle size. I suggest that PrimeVue include a "loadAllComponents" option in the configuration object passed along with the plugin to app.use. Having it off by default is opinionated enough.