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 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 {
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 {
return (
options?.resolve(dMeta, 'directive') ?? {
as: dMeta.as,
from: dMeta.from
};
}
);
}
}
}

View File

@ -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;

View File

@ -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",

View File

@ -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<ModuleOptions>({
},
defaults: {
usePrimeVue: true,
autoImport: false,
resolvePath: undefined,
//cssLayerOrder: undefined,
importPT: undefined,
@ -43,7 +47,7 @@ export default defineNuxtModule<ModuleOptions>({
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<ModuleOptions>({
//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')}
});
`;
}

View File

@ -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);

View File

@ -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);

View File

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