mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-29 19:30:37 +01:00
feat(unplugin): expose options for embedded plugins, throw warnings for duplication (#3207)
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import AutoImports from 'unplugin-auto-import/vite'
|
|
||||||
import VueComponents from 'unplugin-vue-components'
|
|
||||||
|
|
||||||
import ui from '../src/vite'
|
import ui from '../src/vite'
|
||||||
|
|
||||||
@@ -20,12 +18,13 @@ export default defineConfig({
|
|||||||
primary: 'green',
|
primary: 'green',
|
||||||
neutral: 'slate'
|
neutral: 'slate'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
autoImport: {
|
||||||
|
imports: ['vue']
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
dirs: ['../playground/app/components']
|
||||||
}
|
}
|
||||||
}),
|
|
||||||
// these are required as we share the component pages with the Nuxt playground
|
|
||||||
AutoImports({ imports: ['vue'] }),
|
|
||||||
VueComponents.vite({
|
|
||||||
dirs: ['../playground/app/components']
|
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
|
|||||||
20
src/plugins/auto-import.ts
Normal file
20
src/plugins/auto-import.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { join } from 'pathe'
|
||||||
|
import type { UnpluginContextMeta, UnpluginOptions } from 'unplugin'
|
||||||
|
import { defu } from 'defu'
|
||||||
|
|
||||||
|
import { runtimeDir } from '../unplugin'
|
||||||
|
import type { NuxtUIOptions } from '../unplugin'
|
||||||
|
import AutoImport from 'unplugin-auto-import'
|
||||||
|
import type { Options as AutoImportOptions } from 'unplugin-auto-import/types'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This plugin adds all the Nuxt UI composables as auto-imports.
|
||||||
|
*/
|
||||||
|
export default function AutoImportPlugin(options: NuxtUIOptions, meta: UnpluginContextMeta): UnpluginOptions {
|
||||||
|
const pluginOptions = defu(options.autoImport, <AutoImportOptions>{
|
||||||
|
dts: options.dts ?? true,
|
||||||
|
dirs: [join(runtimeDir, 'composables')]
|
||||||
|
})
|
||||||
|
|
||||||
|
return AutoImport.raw(pluginOptions, meta) as UnpluginOptions
|
||||||
|
}
|
||||||
@@ -2,20 +2,35 @@ import { join, normalize } from 'pathe'
|
|||||||
import type { UnpluginContextMeta, UnpluginOptions } from 'unplugin'
|
import type { UnpluginContextMeta, UnpluginOptions } from 'unplugin'
|
||||||
import { globSync } from 'tinyglobby'
|
import { globSync } from 'tinyglobby'
|
||||||
import AutoImportComponents from 'unplugin-vue-components'
|
import AutoImportComponents from 'unplugin-vue-components'
|
||||||
|
import type { Options as ComponentsOptions } from 'unplugin-vue-components/types'
|
||||||
|
|
||||||
import { runtimeDir } from '../unplugin'
|
import { runtimeDir } from '../unplugin'
|
||||||
import type { NuxtUIOptions } from '../unplugin'
|
import type { NuxtUIOptions } from '../unplugin'
|
||||||
|
import { defu } from 'defu'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This plugin adds all the Nuxt UI components as auto-imports.
|
* This plugin adds all the Nuxt UI components as auto-imports.
|
||||||
*/
|
*/
|
||||||
export default function ComponentImportPlugin(framework: UnpluginContextMeta['framework'], options: NuxtUIOptions & { prefix: NonNullable<NuxtUIOptions['prefix']> }) {
|
export default function ComponentImportPlugin(options: NuxtUIOptions & { prefix: NonNullable<NuxtUIOptions['prefix']> }, meta: UnpluginContextMeta) {
|
||||||
const components = globSync('**/*.vue', { cwd: join(runtimeDir, 'components') })
|
const components = globSync('**/*.vue', { cwd: join(runtimeDir, 'components') })
|
||||||
const componentNames = new Set(components.map(c => `${options.prefix}${c.replace(/\.vue$/, '')}`))
|
const componentNames = new Set(components.map(c => `${options.prefix}${c.replace(/\.vue$/, '')}`))
|
||||||
|
|
||||||
const overrides = globSync('**/*.vue', { cwd: join(runtimeDir, 'vue/components') })
|
const overrides = globSync('**/*.vue', { cwd: join(runtimeDir, 'vue/components') })
|
||||||
const overrideNames = new Set(overrides.map(c => `${options.prefix}${c.replace(/\.vue$/, '')}`))
|
const overrideNames = new Set(overrides.map(c => `${options.prefix}${c.replace(/\.vue$/, '')}`))
|
||||||
|
|
||||||
|
const pluginOptions = defu(options.components, <ComponentsOptions>{
|
||||||
|
dts: options.dts ?? true,
|
||||||
|
exclude: [/[\\/]node_modules[\\/](?!\.pnpm|@nuxt\/ui)/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],
|
||||||
|
resolvers: [
|
||||||
|
(componentName) => {
|
||||||
|
if (overrideNames.has(componentName))
|
||||||
|
return { name: 'default', from: join(runtimeDir, 'vue/components', `${componentName.slice(options.prefix.length)}.vue`) }
|
||||||
|
if (componentNames.has(componentName))
|
||||||
|
return { name: 'default', from: join(runtimeDir, 'components', `${componentName.slice(options.prefix.length)}.vue`) }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
return [
|
return [
|
||||||
/**
|
/**
|
||||||
* This plugin aims to ensure we override certain components with Vue-compatible versions:
|
* This plugin aims to ensure we override certain components with Vue-compatible versions:
|
||||||
@@ -41,18 +56,7 @@ export default function ComponentImportPlugin(framework: UnpluginContextMeta['fr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AutoImportComponents[framework]({
|
AutoImportComponents.raw(pluginOptions, meta) as UnpluginOptions
|
||||||
dts: options.dts ?? true,
|
|
||||||
exclude: [/[\\/]node_modules[\\/](?!\.pnpm|@nuxt\/ui)/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/],
|
|
||||||
resolvers: [
|
|
||||||
(componentName) => {
|
|
||||||
if (overrideNames.has(componentName))
|
|
||||||
return { name: 'default', from: join(runtimeDir, 'vue/components', `${componentName.slice(options.prefix.length)}.vue`) }
|
|
||||||
if (componentNames.has(componentName))
|
|
||||||
return { name: 'default', from: join(runtimeDir, 'components', `${componentName.slice(options.prefix.length)}.vue`) }
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
] satisfies UnpluginOptions[]
|
] satisfies UnpluginOptions[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { fileURLToPath } from 'node:url'
|
import { fileURLToPath } from 'node:url'
|
||||||
|
|
||||||
import { join, normalize } from 'pathe'
|
import { normalize } from 'pathe'
|
||||||
|
import type { UnpluginOptions } from 'unplugin'
|
||||||
import { createUnplugin } from 'unplugin'
|
import { createUnplugin } from 'unplugin'
|
||||||
import AutoImport from 'unplugin-auto-import'
|
import type { Options as AutoImportOptions } from 'unplugin-auto-import/types'
|
||||||
|
import type { Options as ComponentsOptions } from 'unplugin-vue-components/types'
|
||||||
import { defu } from 'defu'
|
import { defu } from 'defu'
|
||||||
import tailwind from '@tailwindcss/vite'
|
import tailwind from '@tailwindcss/vite'
|
||||||
import type colors from 'tailwindcss/colors'
|
import type colors from 'tailwindcss/colors'
|
||||||
@@ -20,6 +22,7 @@ import ComponentImportPlugin from './plugins/components'
|
|||||||
import NuxtEnvironmentPlugin from './plugins/nuxt-environment'
|
import NuxtEnvironmentPlugin from './plugins/nuxt-environment'
|
||||||
|
|
||||||
import type { DeepPartial } from './runtime/types/utils'
|
import type { DeepPartial } from './runtime/types/utils'
|
||||||
|
import AutoImportPlugin from './plugins/auto-import'
|
||||||
|
|
||||||
type NeutralColor = 'slate' | 'gray' | 'zinc' | 'neutral' | 'stone'
|
type NeutralColor = 'slate' | 'gray' | 'zinc' | 'neutral' | 'stone'
|
||||||
type Color = Exclude<keyof typeof colors, 'inherit' | 'current' | 'transparent' | 'black' | 'white' | NeutralColor> | (string & {})
|
type Color = Exclude<keyof typeof colors, 'inherit' | 'current' | 'transparent' | 'black' | 'white' | NeutralColor> | (string & {})
|
||||||
@@ -39,6 +42,14 @@ export interface NuxtUIOptions extends Omit<ModuleOptions, 'fonts' | 'colorMode'
|
|||||||
* @defaultValue `true`
|
* @defaultValue `true`
|
||||||
*/
|
*/
|
||||||
colorMode?: boolean
|
colorMode?: boolean
|
||||||
|
/**
|
||||||
|
* Override options for `unplugin-auto-import`
|
||||||
|
*/
|
||||||
|
autoImport?: Partial<AutoImportOptions>
|
||||||
|
/**
|
||||||
|
* Override options for `unplugin-vue-components`
|
||||||
|
*/
|
||||||
|
components?: Partial<ComponentsOptions>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const runtimeDir = normalize(fileURLToPath(new URL('./runtime', import.meta.url)))
|
export const runtimeDir = normalize(fileURLToPath(new URL('./runtime', import.meta.url)))
|
||||||
@@ -53,11 +64,26 @@ export const NuxtUIPlugin = createUnplugin<NuxtUIOptions | undefined>((_options
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
NuxtEnvironmentPlugin(),
|
NuxtEnvironmentPlugin(),
|
||||||
...ComponentImportPlugin(meta.framework, options),
|
ComponentImportPlugin(options, meta),
|
||||||
AutoImport[meta.framework]({ dts: options.dts ?? true, dirs: [join(runtimeDir, 'composables')] }),
|
AutoImportPlugin(options, meta),
|
||||||
tailwind(),
|
tailwind(),
|
||||||
PluginsPlugin(options),
|
PluginsPlugin(options),
|
||||||
TemplatePlugin(options, appConfig),
|
TemplatePlugin(options, appConfig),
|
||||||
AppConfigPlugin(options, appConfig)
|
AppConfigPlugin(options, appConfig),
|
||||||
]
|
<UnpluginOptions>{
|
||||||
|
name: 'nuxt:ui:plugins-duplication-detection',
|
||||||
|
vite: {
|
||||||
|
configResolved(config) {
|
||||||
|
const plugins = config.plugins || []
|
||||||
|
|
||||||
|
if (plugins.filter(i => i.name === 'unplugin-auto-import').length > 1) {
|
||||||
|
throw new Error('[Nuxt UI] Multiple instances of `unplugin-auto-import` detected. Nuxt UI includes `unplugin-auto-import` already, and you can configure it using `autoImport` option in Nuxt UI module options.')
|
||||||
|
}
|
||||||
|
if (plugins.filter(i => i.name === 'unplugin-vue-components').length > 1) {
|
||||||
|
throw new Error('[Nuxt UI] Multiple instances of `unplugin-vue-components` detected. Nuxt UI includes `unplugin-vue-components` already, and you can configure it using `components` option in Nuxt UI module options.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
].flat(1) as UnpluginOptions[]
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user