@primevue/nuxt-module
Version:
Nuxt module for PrimeVue
306 lines (294 loc) • 11.7 kB
JavaScript
import { addComponent, addImports, defineNuxtModule, createResolver, addTemplate, addPlugin, addPluginTemplate } from '@nuxt/kit';
import { isNotEmpty as isNotEmpty$1 } from '@primeuix/utils';
import { PrimeVueResolver } from '@primevue/auto-import-resolver';
import { normalize } from 'pathe';
import Components from 'unplugin-vue-components/nuxt';
import { isFunction, isNotEmpty, resolve, isString } from '@primeuix/utils/object';
import { components, directives, composables } from '@primevue/metadata';
import { createStyleAsString } from '@primeuix/utils/dom';
const Utils = {
object: {
getName(item, options) {
return isFunction(options?.name) ? options.name(item) : `${options.prefix}${item.name}`;
},
getPath(fn, options) {
return isFunction(fn) ? fn(options) : options.from;
},
createStyleAsString(css, options = { name: "" }) {
const { name, ...rest } = options;
return createStyleAsString(css, { "data-primevue-style-id": name, ...rest });
}
}
};
function registerItems(items = [], options = {}, params) {
const included = resolve(options.include, params);
const excluded = resolve(options.exclude, params);
const isMatched = (name, tName) => name?.toLowerCase() === (isString(tName) ? tName?.toLowerCase() : tName?.name?.toLowerCase());
return items.filter((item) => {
const name = item?.name;
const matchedIn = included === "*" || included === void 0 ? true : isNotEmpty(included) ? included.some((inc) => isMatched(name, inc)) : false;
const matchedEx = included === "*" && excluded === "*" ? false : excluded === "*" ? true : isNotEmpty(excluded) ? excluded.some((exc) => isMatched(name, exc)) : false;
return matchedIn && !matchedEx;
});
}
function registerConfig(resolvePath) {
return [
{
name: "PrimeVue",
as: "PrimeVue",
from: resolvePath({ name: "PrimeVue", as: "PrimeVue", from: `primevue/config`, type: "config" })
}
];
}
function registerComponents(resolvePath, moduleOptions) {
const options = moduleOptions.components || {};
const items = registerItems(components, options, { components });
return items.map((item) => {
const _item = { ...item, name: item.name, as: item.name, from: item.from };
const name = Utils.object.getName(_item, options);
const from = resolvePath({ name, as: _item.as, from: _item.from, type: "component" });
const opt = {
export: "default",
name,
filePath: from,
global: true
};
//!moduleOptions.autoImport && addComponent(opt);
addComponent(opt);
return {
..._item,
...opt
};
});
}
function registerDirectives(resolvePath, moduleOptions) {
const options = moduleOptions.directives || {};
const items = registerItems(directives, options, { directives });
return items.map((item) => {
const name = Utils.object.getName(item, options);
const opt = {
...item,
name,
from: resolvePath({ name, as: item.as, from: item.from, type: "directive" })
};
return opt;
});
}
function registerComposables(resolvePath, moduleOptions) {
const options = moduleOptions.composables || {};
const items = registerItems(composables, options, { composables });
return items.map((item) => {
const name = item.name;
const opt = {
...item,
name,
from: resolvePath({ name, as: item.as, from: item.from, type: "composable" })
};
addImports(opt);
return opt;
});
}
function registerServices(resolvePath, registered) {
const services = /* @__PURE__ */ new Set();
registered?.components?.forEach((component) => component?.use && services.add(component.use.as));
return [...services].map((service) => ({
name: service,
as: service,
from: resolvePath({ name: service, as: service, from: `primevue/${service.toLowerCase()}`, type: "service" })
}));
}
function registerStyles(resolvePath, registered, moduleOptions) {
const options = moduleOptions.options || {};
const styles = [
{
name: "BaseStyle",
as: "BaseStyle",
from: resolvePath({ name: "BaseStyle", as: "BaseStyle", from: "@primevue/core/base/style", type: "style" })
}
];
if (!options?.unstyled) {
if (isNotEmpty(registered?.components)) {
styles.push({
name: "BaseComponentStyle",
as: "BaseComponentStyle",
from: resolvePath({ name: "BaseComponentStyle", as: "BaseComponentStyle", from: "@primevue/core/basecomponent/style", type: "style" })
});
}
[registered.components, registered.directives].flat().reduce((acc, citem) => acc.some((item) => item.as.toLowerCase() === citem.as.toLowerCase()) ? acc : [...acc, citem], []).forEach(
(item) => styles.push({
name: `${item.as}Style`,
as: `${item.as}Style`,
from: resolvePath({ name: `${item.as}Style`, as: `${item.as}Style`, from: `${item.from.toLowerCase()}/style`, type: "style" })
})
);
}
return styles;
}
function registerInjectStylesAsString(moduleOptions) {
return [];
}
function registerInjectStylesAsStringToTop(moduleOptions) {
return [Utils.object.createStyleAsString(moduleOptions.cssLayerOrder ? `@layer ${moduleOptions.cssLayerOrder}` : void 0, { name: "layer-order" })];
}
function register(moduleOptions) {
const resolvePath = (resolveOptions) => Utils.object.getPath(moduleOptions.resolvePath, resolveOptions);
const config = registerConfig(resolvePath);
const components2 = registerComponents(resolvePath, moduleOptions);
const directives2 = registerDirectives(resolvePath, moduleOptions);
const composables2 = registerComposables(resolvePath, moduleOptions);
const registered = {
components: components2,
directives: directives2,
composables: composables2
};
const services = registerServices(resolvePath, registered);
const styles = registerStyles(resolvePath, registered, moduleOptions);
const injectStylesAsString = registerInjectStylesAsString();
const injectStylesAsStringToTop = registerInjectStylesAsStringToTop(moduleOptions);
return {
config,
...registered,
services,
styles,
injectStylesAsString,
injectStylesAsStringToTop
};
}
const module = defineNuxtModule({
meta: {
name: "@primevue/nuxt-module",
configKey: "primevue",
compatibility: {
nuxt: ">=3.0.0"
}
},
defaults: {
usePrimeVue: true,
autoImport: true,
resolvePath: void 0,
//cssLayerOrder: undefined,
importPT: void 0,
importTheme: void 0,
loadStyles: true,
options: {},
components: {
prefix: "",
name: void 0,
include: void 0,
exclude: void 0
},
directives: {
prefix: "",
name: void 0,
include: void 0,
exclude: void 0
},
composables: {
//prefix: '',
name: void 0,
include: void 0,
exclude: void 0
}
},
hooks: {},
setup(moduleOptions, nuxt) {
moduleOptions.components.exclude = moduleOptions.components.exclude || ["Editor", "Chart"];
const resolver = createResolver(import.meta.url);
const registered = register(moduleOptions);
const { autoImport, importPT, importTheme, options, loadStyles } = moduleOptions;
const hasTheme = options?.theme !== "none" && (importTheme || options?.theme) && !options?.unstyled;
nuxt.options.runtimeConfig.public.primevue = {
...moduleOptions,
...registered
};
nuxt.options.build.transpile.push("primevue");
hasTheme && nuxt.options.build.transpile.push("@primevue/themes");
hasTheme && nuxt.options.build.transpile.push("@primeuix/themes");
let registeredStyles = registered.styles;
if (autoImport) {
const dts = isNotEmpty$1(moduleOptions.components?.prefix) || isNotEmpty$1(moduleOptions.directives?.prefix);
Components(
{
dts,
resolvers: [
PrimeVueResolver({
components: moduleOptions.components,
directives: moduleOptions.directives
})
]
},
nuxt
);
}
const styleContent = () => {
if (!loadStyles)
return `export const styles = [], stylesToTop = [], themes = [];`;
const uniqueRegisteredStyles = Array.from(new Map(registeredStyles?.map((m) => [m.name, m])).values());
return `
import { useRuntimeConfig } from '#imports';
${uniqueRegisteredStyles?.map((style) => `import ${style.as} from '${style.from}';`).join("\n")}
${hasTheme ? `import { Theme } from '@primeuix/styled';
${importTheme ? `import ${importTheme.as} from '${normalize(importTheme.from)}';
` : ""}` : ""}
const runtimeConfig = useRuntimeConfig();
const config = runtimeConfig?.public?.primevue ?? {};
const { options = {} } = config;
const stylesToTop = [${registered.injectStylesAsStringToTop.join("")}].join('');
const styleProps = {
${options?.csp?.nonce ? `nonce: ${options?.csp?.nonce}` : ""}
}
const styles = [
${registered.injectStylesAsString.join("")},
${uniqueRegisteredStyles?.map((item) => `${item.as} && ${item.as}.getStyleSheet ? ${item.as}.getStyleSheet(undefined, styleProps) : ''`).join(",")}
].join('');
${hasTheme ? `Theme.setTheme(${importTheme?.as} || options?.theme)` : ""}
const themes = ${!hasTheme ? `[]` : `
[
${`${uniqueRegisteredStyles?.[0].as} && ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet ? ${uniqueRegisteredStyles?.[0].as}.getCommonThemeStyleSheet(undefined, styleProps) : ''`},
${uniqueRegisteredStyles?.map((item) => `${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",
getContents: styleContent
}).dst;
addPlugin(resolver.resolve("./runtime/plugin.client"));
addPluginTemplate({
filename: "primevue-plugin.mjs",
getContents() {
return `
import { defineNuxtPlugin, useRuntimeConfig } from '#imports';
${registered.config.map((config) => `import ${config.as} from '${config.from}';`).join("\n")}
${registered.services.map((service) => `import ${service.as} from '${service.from}';`).join("\n")}
${!autoImport && registered.directives.map((directive) => `import ${directive.as} from '${directive.from}';`).join("\n")}
${importPT ? `import ${importPT.as} from '${normalize(importPT.from)}';
` : ""}
${hasTheme && importTheme ? `import ${importTheme.as} from '${normalize(importTheme.from)}';
` : ""}
export default defineNuxtPlugin(({ vueApp }) => {
const runtimeConfig = useRuntimeConfig();
const config = runtimeConfig?.public?.primevue ?? {};
const { usePrimeVue = true, options = {} } = config;
const pt = ${importPT ? `{ pt: ${importPT.as} }` : `{}`};
const theme = ${hasTheme ? `{ theme: ${importTheme?.as} || options?.theme }` : `{}`};
usePrimeVue && vueApp.use(PrimeVue, { ...options, ...pt, ...theme });
${registered.services.map((service) => `vueApp.use(${service.as});`).join("\n")}
${!autoImport && registered.directives.map((directive) => `vueApp.directive('${directive.name}', ${directive.as});`).join("\n")}
});
`;
}
});
nuxt.hook("nitro:config", async (config) => {
config.externals = config.externals || {};
config.externals.inline = config.externals.inline || [];
config.externals.inline.push(resolver.resolve("./runtime/plugin.server"));
config.virtual = config.virtual || {};
config.virtual["#primevue-style"] = styleContent;
config.plugins = config.plugins || [];
config.plugins.push(resolver.resolve("./runtime/plugin.server"));
});
}
});
export { module as default };