@unocss/nuxt
Version:
Nuxt module for UnoCSS
141 lines (136 loc) • 5.37 kB
JavaScript
import { dirname, resolve } from "node:path";
import process from "node:process";
import { fileURLToPath } from "node:url";
import { addComponentsDir, addPluginTemplate, addTemplate, defineNuxtModule, extendViteConfig, extendWebpackConfig, findPath, isNuxtMajorVersion } from "@nuxt/kit";
import { createRecoveryConfigLoader } from "@unocss/config";
import { cssIdRE } from "@unocss/core";
import presetAttributify from "@unocss/preset-attributify";
import presetIcons from "@unocss/preset-icons";
import presetTagify from "@unocss/preset-tagify";
import presetTypography from "@unocss/preset-typography";
import presetWebFonts from "@unocss/preset-web-fonts";
import presetWind3 from "@unocss/preset-wind3";
import presetWind4 from "@unocss/preset-wind4";
//#region ../../virtual-shared/integration/src/defaults.ts
const defaultPipelineExclude = [cssIdRE];
//#endregion
//#region src/options.ts
function resolveOptions(options) {
if (options.wind3 && options.wind4) {
console.warn("[unocss/nuxt]: wind3 and wind4 presets are mutually exclusive. wind3 will be disabled in favor of wind4.");
options.wind3 = false;
}
if (options.presets == null) {
options.presets = [];
const presetMap = {
wind3: presetWind3,
wind4: presetWind4,
attributify: presetAttributify,
icons: presetIcons,
webFonts: presetWebFonts,
typography: presetTypography,
tagify: presetTagify
};
for (const [key, preset] of Object.entries(presetMap)) {
const option = options[key];
if (option) options.presets.push(preset(typeof option === "boolean" ? {} : option));
}
}
options.content ??= {};
options.content.pipeline ??= {};
if (options.content.pipeline !== false) {
options.content.pipeline.exclude ??= defaultPipelineExclude;
if (Array.isArray(options.content.pipeline.exclude)) options.content.pipeline.exclude.push(/\?macro=true/);
}
}
//#endregion
//#region src/index.ts
const dir = dirname(fileURLToPath(import.meta.url));
var src_default = defineNuxtModule({
meta: {
name: "unocss",
configKey: "unocss"
},
defaults: {
mode: "global",
autoImport: true,
preflight: false,
components: true,
disableNuxtInlineStyle: true,
nuxtLayers: false,
attributify: false,
webFonts: false,
icons: false,
wind3: true,
wind4: false
},
async setup(options, nuxt) {
resolveOptions(options);
const loadConfig = createRecoveryConfigLoader();
options.mode ??= "global";
const InjectModes = ["global", "dist-chunk"];
if (options.disableNuxtInlineStyle) {
nuxt.options.features ||= {};
nuxt.options.features.inlineStyles = false;
}
if (options.injectPosition != null) console.warn("[unocss/nuxt] options `injectPosition` is temporary removed due to the incompatibility with Nuxt 3.9. We are seeking for better solution. It's not effective at this moment.");
if (options.autoImport) addPluginTemplate({
filename: "unocss.mjs",
getContents: () => {
const lines = [InjectModes.includes(options.mode) ? "import 'uno.css'" : "", "import { defineNuxtPlugin } from '#imports'; export default defineNuxtPlugin(() => {})"];
if (options.preflight) lines.unshift("import '@unocss/reset/tailwind.css'");
return lines.join("\n");
}
});
if (options.components) addComponentsDir({
path: resolve(dir, "../runtime"),
watch: false
});
if (options.nuxtLayers) addTemplate({
filename: "uno.config.mjs",
async getContents() {
const configPaths = (await Promise.all(nuxt.options._layers.slice(1).map((layer) => findPath(options.configFile || ["uno.config", "unocss.config"], { cwd: layer.config.rootDir })))).filter(Boolean).reverse();
return `import { mergeConfigs } from '@unocss/core'
${configPaths.map((path, index) => `import cfg${index} from '${path}'`.trimStart()).join("\n").trimEnd()}
export default mergeConfigs([${configPaths.map((_, index) => `cfg${index}`).join(", ")}])
`;
},
write: true
});
nuxt.hook("build:before", async () => {
const { config: unoConfig } = await loadConfig(process.cwd(), { configFile: options.configFile }, [], options);
if (isNuxtMajorVersion(3, nuxt) && nuxt.options.builder === "@nuxt/vite-builder" && nuxt.options.postcss.plugins.cssnano && unoConfig.transformers?.some((t) => t.name === "@unocss/transformer-directives" && t.enforce !== "pre")) {
const preset = nuxt.options.postcss.plugins.cssnano.preset;
nuxt.options.postcss.plugins.cssnano = { preset: [preset?.[0] || "default", Object.assign({
mergeRules: false,
normalizeWhitespace: false,
discardComments: false
}, preset?.[1])] };
}
await nuxt.callHook("unocss:config", unoConfig);
extendViteConfig(async (config) => {
const { default: VitePlugin } = await import("@unocss/vite");
config.plugins = config.plugins || [];
config.plugins.unshift(...VitePlugin({ mode: options.mode }, unoConfig));
});
extendWebpackConfig(async (config) => {
const { default: WebpackPlugin } = await import("@unocss/webpack");
config.plugins = config.plugins || [];
config.plugins.unshift(WebpackPlugin({}, unoConfig));
});
});
if (nuxt.options.dev) nuxt.hook("devtools:customTabs", (tabs) => {
tabs.push({
title: "UnoCSS",
name: "unocss",
icon: "/__unocss/favicon.svg",
view: {
type: "iframe",
src: "/__unocss/"
}
});
});
}
});
//#endregion
export { src_default as default };