From 9b9af73668c6a2fad1e09b264de74efed8413d22 Mon Sep 17 00:00:00 2001 From: Mert Sincan Date: Thu, 20 Jun 2024 13:49:15 +0100 Subject: [PATCH] Fixed #5935 - Add autoImport option to @primevue/nuxt-module --- packages/auto-import-resolver/index.ts | 27 +++++---- packages/metadata/src/index.ts | 1 + packages/nuxt-module/package.json | 5 +- packages/nuxt-module/src/module.ts | 55 +++++++++++++++---- packages/nuxt-module/src/register.ts | 33 ++++++----- .../nuxt-module/src/runtime/plugin.server.ts | 11 +++- packages/nuxt-module/src/types.d.ts | 1 + 7 files changed, 95 insertions(+), 38 deletions(-) diff --git a/packages/auto-import-resolver/index.ts b/packages/auto-import-resolver/index.ts index 9c204ca6c..1c6e9dfa5 100644 --- a/packages/auto-import-resolver/index.ts +++ b/packages/auto-import-resolver/index.ts @@ -1,5 +1,5 @@ -import { components, directives } from '@primevue/metadata'; -import type { ComponentResolver } from 'unplugin-vue-components/types'; +import { components, directives, type MetaType } from '@primevue/metadata'; +import type { ComponentResolveResult, ComponentResolver } from 'unplugin-vue-components/types'; export interface PrimeVueResolverOptions { components?: { @@ -8,6 +8,7 @@ export interface PrimeVueResolverOptions { directives?: { prefix?: string; }; + resolve?: (meta: MetaType, type: string) => ComponentResolveResult; } export function PrimeVueResolver(options: PrimeVueResolverOptions = {}): ComponentResolver[] { @@ -27,12 +28,14 @@ export function PrimeVueResolver(options: PrimeVueResolverOptions = {}): Compone resolve: (name: string) => { const { prefix } = options.components || {}; const cName = getName(name, prefix); - const cMeta = components.find((c) => c.name === cName); + const cMeta = components.find((c) => c.name.toLocaleLowerCase() === cName.toLocaleLowerCase()); if (cMeta) { - return { - from: cMeta.from - }; + return ( + options?.resolve(cMeta, 'component') ?? { + from: cMeta.from + } + ); } } }, @@ -41,13 +44,15 @@ export function PrimeVueResolver(options: PrimeVueResolverOptions = {}): Compone resolve: (name: string) => { const { prefix } = options.directives || {}; const dName = getName(name, prefix); - const dMeta = directives.find((d) => d.name === dName); + const dMeta = directives.find((d) => d.name.toLocaleLowerCase() === dName.toLocaleLowerCase()); if (dMeta) { - return { - as: dMeta.as, - from: dMeta.from - }; + return ( + options?.resolve(dMeta, 'directive') ?? { + as: dMeta.as, + from: dMeta.from + } + ); } } } diff --git a/packages/metadata/src/index.ts b/packages/metadata/src/index.ts index a77e85b05..4f371e6ce 100644 --- a/packages/metadata/src/index.ts +++ b/packages/metadata/src/index.ts @@ -11,6 +11,7 @@ export function toMeta(arr?: any[]): MetaType[] | undefined { return arr?.map((item) => { const it = typeof item === 'string' ? { name: item } : item; + it.as ??= it?.name; it.from ??= `primevue/${it?.name?.toLowerCase()}`; return it; diff --git a/packages/nuxt-module/package.json b/packages/nuxt-module/package.json index e8e11f8b1..16c83f9fe 100644 --- a/packages/nuxt-module/package.json +++ b/packages/nuxt-module/package.json @@ -59,7 +59,8 @@ "@nuxt/kit": "^3.7.3", "pathe": "^1.1.2", "primevue": "workspace:*", - "@primevue/metadata": "workspace:*" + "@primevue/auto-import-resolver": "workspace:*", + "unplugin-vue-components": "0.27.0" }, "devDependencies": { "@types/node": "^18.17.17", @@ -76,4 +77,4 @@ "engines": { "node": ">=12.11.0" } -} \ No newline at end of file +} diff --git a/packages/nuxt-module/src/module.ts b/packages/nuxt-module/src/module.ts index b412d94e9..df09b8cb0 100644 --- a/packages/nuxt-module/src/module.ts +++ b/packages/nuxt-module/src/module.ts @@ -1,5 +1,8 @@ import { addPlugin, addPluginTemplate, addTemplate, createResolver, defineNuxtModule } from '@nuxt/kit'; +import { PrimeVueResolver } from '@primevue/auto-import-resolver'; +import type { MetaType } from '@primevue/metadata'; import { normalize } from 'pathe'; +import Components from 'unplugin-vue-components/nuxt'; import { register } from './register'; import type { ModuleOptions } from './types'; @@ -13,6 +16,7 @@ export default defineNuxtModule({ }, defaults: { usePrimeVue: true, + autoImport: false, resolvePath: undefined, //cssLayerOrder: undefined, importPT: undefined, @@ -43,7 +47,7 @@ export default defineNuxtModule({ const resolver = createResolver(import.meta.url); const registered = register(moduleOptions); - const { importPT, importTheme, options } = moduleOptions; + const { autoImport, importPT, importTheme, options } = moduleOptions; const hasTheme = importTheme && !options?.unstyled; nuxt.options.runtimeConfig.public.primevue = { @@ -54,8 +58,36 @@ export default defineNuxtModule({ //nuxt.options.build.transpile.push('nuxt'); nuxt.options.build.transpile.push('primevue'); - const styleContent = () => ` -${registered.styles.map((style: any) => `import ${style.as} from '${style.from}';`).join('\n')} + let registeredStyles: MetaType[] = registered.styles; + + if (autoImport) { + Components( + { + dts: false, + resolvers: [ + PrimeVueResolver({ + components: moduleOptions.components, + directives: moduleOptions.directives, + resolve: (meta: MetaType) => { + registeredStyles.push({ + ...meta, + name: `${meta.name}Style`, + as: `${meta.as}Style`, + from: `${meta.from}/style` + }); + } + }) + ] + }, + nuxt + ); + } + + const styleContent = () => { + const uniqueRegisteredStyles = Array.from(new Map(registeredStyles?.map((m: MetaType) => [m.name, m])).values()); + + return ` +${uniqueRegisteredStyles?.map((style: MetaType) => `import ${style.as} from '${style.from}';`).join('\n')} ${ hasTheme ? `import { Theme } from '@primeuix/styled'; @@ -69,18 +101,19 @@ const styleProps = { } const styles = [ ${registered.injectStylesAsString.join('')}, - ${registered.styles.map((item) => `${item.as} && ${item.as}.getStyleSheet ? ${item.as}.getStyleSheet(undefined, styleProps) : ''`).join(',')} + ${uniqueRegisteredStyles?.map((item: MetaType) => `${item.as} && ${item.as}.getStyleSheet ? ${item.as}.getStyleSheet(undefined, styleProps) : ''`).join(',')} ].join(''); ${hasTheme ? `Theme.setTheme(${importTheme.as})` : ''} const themes = [ - ${hasTheme ? `${registered.styles[0].as} && ${registered.styles[0].as}.getCommonThemeStyleSheet ? ${registered.styles[0].as}.getCommonThemeStyleSheet(undefined, styleProps) : ''` : ''}, - ${hasTheme ? registered.styles.map((item) => `${item.as} && ${item.as}.getThemeStyleSheet ? ${item.as}.getThemeStyleSheet(undefined, styleProps) : ''`).join(',') : ''} + ${`${uniqueRegisteredStyles?.[0].as} && ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet ? ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet(undefined, styleProps) : ''`}, + ${uniqueRegisteredStyles?.map((item: MetaType) => `${item.as} && ${item.as}.getThemeStyleSheet ? ${item.as}.getThemeStyleSheet(undefined, styleProps) : ''`).join(',')} ].join(''); export { styles, stylesToTop, themes }; `; + }; nuxt.options.alias['#primevue-style'] = addTemplate({ filename: 'primevue-style.mjs', @@ -94,9 +127,9 @@ export { styles, stylesToTop, themes }; getContents() { return ` import { defineNuxtPlugin, useRuntimeConfig } from '#imports'; -${registered.config.map((config: any) => `import ${config.as} from '${config.from}';`).join('\n')} -${registered.services.map((service: any) => `import ${service.as} from '${service.from}';`).join('\n')} -${registered.directives.map((directive: any) => `import ${directive.as} from '${directive.from}';`).join('\n')} +${registered.config.map((config: MetaType) => `import ${config.as} from '${config.from}';`).join('\n')} +${registered.services.map((service: MetaType) => `import ${service.as} from '${service.from}';`).join('\n')} +${!autoImport && registered.directives.map((directive: MetaType) => `import ${directive.as} from '${directive.from}';`).join('\n')} ${importPT ? `import ${importPT.as} from '${normalize(importPT.from)}';\n` : ''} ${hasTheme ? `import ${importTheme.as} from '${normalize(importTheme.from)}';\n` : ''} @@ -108,8 +141,8 @@ export default defineNuxtPlugin(({ vueApp }) => { const theme = ${hasTheme ? `{ theme: ${importTheme.as} }` : `{}`}; usePrimeVue && vueApp.use(PrimeVue, { ...options, ...pt, ...theme }); - ${registered.services.map((service: any) => `vueApp.use(${service.as});`).join('\n')} - ${registered.directives.map((directive: any) => `vueApp.directive('${directive.name}', ${directive.as});`).join('\n')} + ${registered.services.map((service: MetaType) => `vueApp.use(${service.as});`).join('\n')} + ${!autoImport && registered.directives.map((directive: MetaType) => `vueApp.directive('${directive.name}', ${directive.as});`).join('\n')} }); `; } diff --git a/packages/nuxt-module/src/register.ts b/packages/nuxt-module/src/register.ts index 265037b07..b6c57fd18 100644 --- a/packages/nuxt-module/src/register.ts +++ b/packages/nuxt-module/src/register.ts @@ -1,6 +1,7 @@ import { addComponent, addImports } from '@nuxt/kit'; import type { MetaType } from '@primevue/metadata'; import { components, composables, directives } from '@primevue/metadata'; +import type { PrimeVueConfiguration } from 'primevue/config'; import type { ConstructsType, ModuleOptions, ResolvePathOptions } from './types'; import { Utils } from './utils'; @@ -28,7 +29,8 @@ function registerConfig(resolvePath: any) { ]; } -function registerComponents(resolvePath: any, options: ConstructsType = {}) { +function registerComponents(resolvePath: any, moduleOptions: ModuleOptions) { + const options: ConstructsType = moduleOptions.components || {}; const items: MetaType[] = registerItems(components, options, { components }); return items.map((item: MetaType) => { @@ -42,7 +44,7 @@ function registerComponents(resolvePath: any, options: ConstructsType = {}) { global: true }; - addComponent(opt); + !moduleOptions.autoImport && addComponent(opt); return { ..._item, @@ -51,7 +53,8 @@ function registerComponents(resolvePath: any, options: ConstructsType = {}) { }); } -function registerDirectives(resolvePath: any, options: ConstructsType = {}) { +function registerDirectives(resolvePath: any, moduleOptions: ModuleOptions) { + const options: ConstructsType = moduleOptions.directives || {}; const items: MetaType[] = registerItems(directives, options, { directives }); return items.map((item: MetaType) => { @@ -66,7 +69,8 @@ function registerDirectives(resolvePath: any, options: ConstructsType = {}) { }); } -function registerComposables(resolvePath: any, options: ConstructsType = {}) { +function registerComposables(resolvePath: any, moduleOptions: ModuleOptions) { + const options: ConstructsType = moduleOptions.composables || {}; const items: MetaType[] = registerItems(composables, options, { composables }); return items.map((item: MetaType) => { @@ -95,7 +99,9 @@ function registerServices(resolvePath: any, registered: any) { })); } -function registerStyles(resolvePath: any, registered: any, options: any) { +function registerStyles(resolvePath: any, registered: any, moduleOptions: ModuleOptions) { + const options: PrimeVueConfiguration = moduleOptions.options || {}; + const styles: MetaType[] = [ { name: 'BaseStyle', @@ -104,7 +110,7 @@ function registerStyles(resolvePath: any, registered: any, options: any) { } ]; - if (!options?.unstyled) { + if (!moduleOptions.autoImport && !options?.unstyled) { if (Utils.object.isNotEmpty(registered?.components)) { styles.push({ name: 'BaseComponentStyle', @@ -128,28 +134,29 @@ function registerStyles(resolvePath: any, registered: any, options: any) { return styles; } -function registerInjectStylesAsString(options: any) { +function registerInjectStylesAsString(moduleOptions: ModuleOptions) { return []; } -function registerInjectStylesAsStringToTop(options: any) { - return [Utils.object.createStyleAsString(options.cssLayerOrder ? `@layer ${options.cssLayerOrder}` : undefined, { name: 'layer-order' })]; +function registerInjectStylesAsStringToTop(moduleOptions: any) { + // @todo - Remove `cssLayerOrder` + return [Utils.object.createStyleAsString(moduleOptions.cssLayerOrder ? `@layer ${moduleOptions.cssLayerOrder}` : undefined, { name: 'layer-order' })]; } export function register(moduleOptions: ModuleOptions) { const resolvePath = (resolveOptions: ResolvePathOptions) => Utils.object.getPath(moduleOptions.resolvePath, resolveOptions); const config = registerConfig(resolvePath); - const components = registerComponents(resolvePath, moduleOptions.components); - const directives = registerDirectives(resolvePath, moduleOptions.directives); - const composables = registerComposables(resolvePath, moduleOptions.composables); + const components = registerComponents(resolvePath, moduleOptions); + const directives = registerDirectives(resolvePath, moduleOptions); + const composables = registerComposables(resolvePath, moduleOptions); const registered = { components, directives, composables }; const services = registerServices(resolvePath, registered); - const styles = registerStyles(resolvePath, registered, moduleOptions.options); + const styles = registerStyles(resolvePath, registered, moduleOptions); const injectStylesAsString = registerInjectStylesAsString(moduleOptions); const injectStylesAsStringToTop = registerInjectStylesAsStringToTop(moduleOptions); diff --git a/packages/nuxt-module/src/runtime/plugin.server.ts b/packages/nuxt-module/src/runtime/plugin.server.ts index 99ce77a23..5fb07d560 100644 --- a/packages/nuxt-module/src/runtime/plugin.server.ts +++ b/packages/nuxt-module/src/runtime/plugin.server.ts @@ -5,10 +5,19 @@ import { styles, stylesToTop, themes } from '#primevue-style'; type NitroAppPlugin = (nitro: NitroApp) => void; +interface NuxtRenderHTMLContext { + htmlAttrs: string[]; + head: string[]; + bodyAttrs: string[]; + bodyPreprend: string[]; + body: string[]; + bodyAppend: string[]; +} + const defineNitroPlugin = (def: NitroAppPlugin): NitroAppPlugin => def; export default defineNitroPlugin(async (nitroApp) => { - nitroApp.hooks.hook('render:html' as any, (html: any) => { + nitroApp.hooks.hook('render:html' as any, (html: NuxtRenderHTMLContext) => { html.head.unshift(stylesToTop); html.head.push(styles); html.head.push(themes); diff --git a/packages/nuxt-module/src/types.d.ts b/packages/nuxt-module/src/types.d.ts index 40717d6b3..0d91f4547 100644 --- a/packages/nuxt-module/src/types.d.ts +++ b/packages/nuxt-module/src/types.d.ts @@ -9,6 +9,7 @@ export interface ConstructsType { export interface ModuleOptions { usePrimeVue?: boolean; + autoImport?: boolean; resolvePath?: any; /*cssLayerOrder?: string;*/ importPT?: ImportOptions;