UNPKG

@unocss/nuxt

Version:

Nuxt module for UnoCSS

141 lines (136 loc) 5.37 kB
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 };