Fixed #5935 - Add autoImport option to @primevue/nuxt-module

pull/5940/head
Mert Sincan 2024-06-20 13:49:15 +01:00
parent 299c44a02d
commit 9b9af73668
7 changed files with 95 additions and 38 deletions

View File

@ -1,5 +1,5 @@
import { components, directives } from '@primevue/metadata'; import { components, directives, type MetaType } from '@primevue/metadata';
import type { ComponentResolver } from 'unplugin-vue-components/types'; import type { ComponentResolveResult, ComponentResolver } from 'unplugin-vue-components/types';
export interface PrimeVueResolverOptions { export interface PrimeVueResolverOptions {
components?: { components?: {
@ -8,6 +8,7 @@ export interface PrimeVueResolverOptions {
directives?: { directives?: {
prefix?: string; prefix?: string;
}; };
resolve?: (meta: MetaType, type: string) => ComponentResolveResult;
} }
export function PrimeVueResolver(options: PrimeVueResolverOptions = {}): ComponentResolver[] { export function PrimeVueResolver(options: PrimeVueResolverOptions = {}): ComponentResolver[] {
@ -27,12 +28,14 @@ export function PrimeVueResolver(options: PrimeVueResolverOptions = {}): Compone
resolve: (name: string) => { resolve: (name: string) => {
const { prefix } = options.components || {}; const { prefix } = options.components || {};
const cName = getName(name, prefix); 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) { if (cMeta) {
return { return (
from: cMeta.from options?.resolve(cMeta, 'component') ?? {
}; from: cMeta.from
}
);
} }
} }
}, },
@ -41,13 +44,15 @@ export function PrimeVueResolver(options: PrimeVueResolverOptions = {}): Compone
resolve: (name: string) => { resolve: (name: string) => {
const { prefix } = options.directives || {}; const { prefix } = options.directives || {};
const dName = getName(name, prefix); 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) { if (dMeta) {
return { return (
as: dMeta.as, options?.resolve(dMeta, 'directive') ?? {
from: dMeta.from as: dMeta.as,
}; from: dMeta.from
}
);
} }
} }
} }

View File

@ -11,6 +11,7 @@ export function toMeta(arr?: any[]): MetaType[] | undefined {
return arr?.map((item) => { return arr?.map((item) => {
const it = typeof item === 'string' ? { name: item } : item; const it = typeof item === 'string' ? { name: item } : item;
it.as ??= it?.name;
it.from ??= `primevue/${it?.name?.toLowerCase()}`; it.from ??= `primevue/${it?.name?.toLowerCase()}`;
return it; return it;

View File

@ -59,7 +59,8 @@
"@nuxt/kit": "^3.7.3", "@nuxt/kit": "^3.7.3",
"pathe": "^1.1.2", "pathe": "^1.1.2",
"primevue": "workspace:*", "primevue": "workspace:*",
"@primevue/metadata": "workspace:*" "@primevue/auto-import-resolver": "workspace:*",
"unplugin-vue-components": "0.27.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^18.17.17", "@types/node": "^18.17.17",

View File

@ -1,5 +1,8 @@
import { addPlugin, addPluginTemplate, addTemplate, createResolver, defineNuxtModule } from '@nuxt/kit'; 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 { normalize } from 'pathe';
import Components from 'unplugin-vue-components/nuxt';
import { register } from './register'; import { register } from './register';
import type { ModuleOptions } from './types'; import type { ModuleOptions } from './types';
@ -13,6 +16,7 @@ export default defineNuxtModule<ModuleOptions>({
}, },
defaults: { defaults: {
usePrimeVue: true, usePrimeVue: true,
autoImport: false,
resolvePath: undefined, resolvePath: undefined,
//cssLayerOrder: undefined, //cssLayerOrder: undefined,
importPT: undefined, importPT: undefined,
@ -43,7 +47,7 @@ export default defineNuxtModule<ModuleOptions>({
const resolver = createResolver(import.meta.url); const resolver = createResolver(import.meta.url);
const registered = register(moduleOptions); const registered = register(moduleOptions);
const { importPT, importTheme, options } = moduleOptions; const { autoImport, importPT, importTheme, options } = moduleOptions;
const hasTheme = importTheme && !options?.unstyled; const hasTheme = importTheme && !options?.unstyled;
nuxt.options.runtimeConfig.public.primevue = { nuxt.options.runtimeConfig.public.primevue = {
@ -54,8 +58,36 @@ export default defineNuxtModule<ModuleOptions>({
//nuxt.options.build.transpile.push('nuxt'); //nuxt.options.build.transpile.push('nuxt');
nuxt.options.build.transpile.push('primevue'); nuxt.options.build.transpile.push('primevue');
const styleContent = () => ` let registeredStyles: MetaType[] = registered.styles;
${registered.styles.map((style: any) => `import ${style.as} from '${style.from}';`).join('\n')}
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 hasTheme
? `import { Theme } from '@primeuix/styled'; ? `import { Theme } from '@primeuix/styled';
@ -69,18 +101,19 @@ const styleProps = {
} }
const styles = [ const styles = [
${registered.injectStylesAsString.join('')}, ${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(''); ].join('');
${hasTheme ? `Theme.setTheme(${importTheme.as})` : ''} ${hasTheme ? `Theme.setTheme(${importTheme.as})` : ''}
const themes = [ const themes = [
${hasTheme ? `${registered.styles[0].as} && ${registered.styles[0].as}.getCommonThemeStyleSheet ? ${registered.styles[0].as}.getCommonThemeStyleSheet(undefined, styleProps) : ''` : ''}, ${`${uniqueRegisteredStyles?.[0].as} && ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet ? ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet(undefined, styleProps) : ''`},
${hasTheme ? registered.styles.map((item) => `${item.as} && ${item.as}.getThemeStyleSheet ? ${item.as}.getThemeStyleSheet(undefined, styleProps) : ''`).join(',') : ''} ${uniqueRegisteredStyles?.map((item: MetaType) => `${item.as} && ${item.as}.getThemeStyleSheet ? ${item.as}.getThemeStyleSheet(undefined, styleProps) : ''`).join(',')}
].join(''); ].join('');
export { styles, stylesToTop, themes }; export { styles, stylesToTop, themes };
`; `;
};
nuxt.options.alias['#primevue-style'] = addTemplate({ nuxt.options.alias['#primevue-style'] = addTemplate({
filename: 'primevue-style.mjs', filename: 'primevue-style.mjs',
@ -94,9 +127,9 @@ export { styles, stylesToTop, themes };
getContents() { getContents() {
return ` return `
import { defineNuxtPlugin, useRuntimeConfig } from '#imports'; import { defineNuxtPlugin, useRuntimeConfig } from '#imports';
${registered.config.map((config: any) => `import ${config.as} from '${config.from}';`).join('\n')} ${registered.config.map((config: MetaType) => `import ${config.as} from '${config.from}';`).join('\n')}
${registered.services.map((service: any) => `import ${service.as} from '${service.from}';`).join('\n')} ${registered.services.map((service: MetaType) => `import ${service.as} from '${service.from}';`).join('\n')}
${registered.directives.map((directive: any) => `import ${directive.as} from '${directive.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` : ''} ${importPT ? `import ${importPT.as} from '${normalize(importPT.from)}';\n` : ''}
${hasTheme ? `import ${importTheme.as} from '${normalize(importTheme.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} }` : `{}`}; const theme = ${hasTheme ? `{ theme: ${importTheme.as} }` : `{}`};
usePrimeVue && vueApp.use(PrimeVue, { ...options, ...pt, ...theme }); usePrimeVue && vueApp.use(PrimeVue, { ...options, ...pt, ...theme });
${registered.services.map((service: any) => `vueApp.use(${service.as});`).join('\n')} ${registered.services.map((service: MetaType) => `vueApp.use(${service.as});`).join('\n')}
${registered.directives.map((directive: any) => `vueApp.directive('${directive.name}', ${directive.as});`).join('\n')} ${!autoImport && registered.directives.map((directive: MetaType) => `vueApp.directive('${directive.name}', ${directive.as});`).join('\n')}
}); });
`; `;
} }

View File

@ -1,6 +1,7 @@
import { addComponent, addImports } from '@nuxt/kit'; import { addComponent, addImports } from '@nuxt/kit';
import type { MetaType } from '@primevue/metadata'; import type { MetaType } from '@primevue/metadata';
import { components, composables, directives } from '@primevue/metadata'; import { components, composables, directives } from '@primevue/metadata';
import type { PrimeVueConfiguration } from 'primevue/config';
import type { ConstructsType, ModuleOptions, ResolvePathOptions } from './types'; import type { ConstructsType, ModuleOptions, ResolvePathOptions } from './types';
import { Utils } from './utils'; 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 }); const items: MetaType[] = registerItems(components, options, { components });
return items.map((item: MetaType) => { return items.map((item: MetaType) => {
@ -42,7 +44,7 @@ function registerComponents(resolvePath: any, options: ConstructsType = {}) {
global: true global: true
}; };
addComponent(opt); !moduleOptions.autoImport && addComponent(opt);
return { return {
..._item, ..._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 }); const items: MetaType[] = registerItems(directives, options, { directives });
return items.map((item: MetaType) => { 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 }); const items: MetaType[] = registerItems(composables, options, { composables });
return items.map((item: MetaType) => { 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[] = [ const styles: MetaType[] = [
{ {
name: 'BaseStyle', 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)) { if (Utils.object.isNotEmpty(registered?.components)) {
styles.push({ styles.push({
name: 'BaseComponentStyle', name: 'BaseComponentStyle',
@ -128,28 +134,29 @@ function registerStyles(resolvePath: any, registered: any, options: any) {
return styles; return styles;
} }
function registerInjectStylesAsString(options: any) { function registerInjectStylesAsString(moduleOptions: ModuleOptions) {
return []; return [];
} }
function registerInjectStylesAsStringToTop(options: any) { function registerInjectStylesAsStringToTop(moduleOptions: any) {
return [Utils.object.createStyleAsString(options.cssLayerOrder ? `@layer ${options.cssLayerOrder}` : undefined, { name: 'layer-order' })]; // @todo - Remove `cssLayerOrder`
return [Utils.object.createStyleAsString(moduleOptions.cssLayerOrder ? `@layer ${moduleOptions.cssLayerOrder}` : undefined, { name: 'layer-order' })];
} }
export function register(moduleOptions: ModuleOptions) { export function register(moduleOptions: ModuleOptions) {
const resolvePath = (resolveOptions: ResolvePathOptions) => Utils.object.getPath(moduleOptions.resolvePath, resolveOptions); const resolvePath = (resolveOptions: ResolvePathOptions) => Utils.object.getPath(moduleOptions.resolvePath, resolveOptions);
const config = registerConfig(resolvePath); const config = registerConfig(resolvePath);
const components = registerComponents(resolvePath, moduleOptions.components); const components = registerComponents(resolvePath, moduleOptions);
const directives = registerDirectives(resolvePath, moduleOptions.directives); const directives = registerDirectives(resolvePath, moduleOptions);
const composables = registerComposables(resolvePath, moduleOptions.composables); const composables = registerComposables(resolvePath, moduleOptions);
const registered = { const registered = {
components, components,
directives, directives,
composables composables
}; };
const services = registerServices(resolvePath, registered); const services = registerServices(resolvePath, registered);
const styles = registerStyles(resolvePath, registered, moduleOptions.options); const styles = registerStyles(resolvePath, registered, moduleOptions);
const injectStylesAsString = registerInjectStylesAsString(moduleOptions); const injectStylesAsString = registerInjectStylesAsString(moduleOptions);
const injectStylesAsStringToTop = registerInjectStylesAsStringToTop(moduleOptions); const injectStylesAsStringToTop = registerInjectStylesAsStringToTop(moduleOptions);

View File

@ -5,10 +5,19 @@ import { styles, stylesToTop, themes } from '#primevue-style';
type NitroAppPlugin = (nitro: NitroApp) => void; 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; const defineNitroPlugin = (def: NitroAppPlugin): NitroAppPlugin => def;
export default defineNitroPlugin(async (nitroApp) => { 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.unshift(stylesToTop);
html.head.push(styles); html.head.push(styles);
html.head.push(themes); html.head.push(themes);

View File

@ -9,6 +9,7 @@ export interface ConstructsType {
export interface ModuleOptions { export interface ModuleOptions {
usePrimeVue?: boolean; usePrimeVue?: boolean;
autoImport?: boolean;
resolvePath?: any; resolvePath?: any;
/*cssLayerOrder?: string;*/ /*cssLayerOrder?: string;*/
importPT?: ImportOptions; importPT?: ImportOptions;