From 44e3d4e87f36e95d1ab27d3f875df7de5c7c2ecd Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Fri, 9 Aug 2024 13:10:48 +0100 Subject: [PATCH] fix(vite,webpack): handle local postcss plugins (#28481) --- packages/vite/src/css.ts | 20 +++++++++++++++----- packages/webpack/src/utils/postcss.ts | 20 +++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/packages/vite/src/css.ts b/packages/vite/src/css.ts index 954d630a8c..ecf0548a1d 100644 --- a/packages/vite/src/css.ts +++ b/packages/vite/src/css.ts @@ -1,9 +1,10 @@ import { fileURLToPath, pathToFileURL } from 'node:url' -import { requireModule, tryResolveModule } from '@nuxt/kit' +import { requireModule, resolveAlias, tryResolveModule } from '@nuxt/kit' import type { Nuxt, NuxtOptions } from '@nuxt/schema' import type { InlineConfig as ViteConfig } from 'vite' import { interopDefault } from 'mlly' import type { Plugin } from 'postcss' +import { isAbsolute, resolve } from 'pathe' function sortPlugins ({ plugins, order }: NuxtOptions['postcss']): string[] { const names = Object.keys(plugins) @@ -26,16 +27,25 @@ export async function resolveCSSOptions (nuxt: Nuxt): Promise const pluginOptions = postcssOptions.plugins[pluginName] if (!pluginOptions) { continue } - const path = await tryResolveModule(pluginName, nuxt.options.modulesDir) - + let pluginPath: string | undefined = resolveAlias(pluginName, nuxt.options.alias) let pluginFn: (opts: Record) => Plugin + + if (pluginPath[0] === '.') { + pluginPath = resolve(nuxt.options.rootDir, pluginPath) + } + + const path = await tryResolveModule(pluginPath, nuxt.options.modulesDir) + // TODO: use jiti v2 if (path) { pluginFn = await import(pathToFileURL(path).href).then(interopDefault) } else { - console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`) + // warn for libraries, not for local plugins + if (!isAbsolute(pluginPath)) { + console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`) + } // fall back to cjs - pluginFn = requireModule(pluginName, { paths: [cwd] }) + pluginFn = requireModule(pluginPath, { paths: [cwd] }) } if (typeof pluginFn === 'function') { css.postcss.plugins.push(pluginFn(pluginOptions)) diff --git a/packages/webpack/src/utils/postcss.ts b/packages/webpack/src/utils/postcss.ts index 2260f40948..26cbb8ba02 100644 --- a/packages/webpack/src/utils/postcss.ts +++ b/packages/webpack/src/utils/postcss.ts @@ -1,10 +1,11 @@ import { fileURLToPath, pathToFileURL } from 'node:url' import createResolver from 'postcss-import-resolver' import { interopDefault } from 'mlly' -import { requireModule, tryResolveModule } from '@nuxt/kit' +import { requireModule, resolveAlias, tryResolveModule } from '@nuxt/kit' import type { Nuxt, NuxtOptions } from '@nuxt/schema' import { defu } from 'defu' import type { Plugin } from 'postcss' +import { isAbsolute, resolve } from 'pathe' const isPureObject = (obj: unknown): obj is object => obj !== null && !Array.isArray(obj) && typeof obj === 'object' @@ -47,16 +48,25 @@ export async function getPostcssConfig (nuxt: Nuxt) { const pluginOptions = postcssOptions.plugins[pluginName] if (!pluginOptions) { continue } - const path = await tryResolveModule(pluginName, nuxt.options.modulesDir) - + let pluginPath: string | undefined = resolveAlias(pluginName, nuxt.options.alias) let pluginFn: (opts: Record) => Plugin + + if (pluginPath[0] === '.') { + pluginPath = resolve(nuxt.options.rootDir, pluginPath) + } + + const path = await tryResolveModule(pluginPath, nuxt.options.modulesDir) + // TODO: use jiti v2 if (path) { pluginFn = await import(pathToFileURL(path).href).then(interopDefault) } else { - console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`) + // warn for libraries, not for local plugins + if (!isAbsolute(pluginPath)) { + console.warn(`[nuxt] could not import postcss plugin \`${pluginName}\` with ESM. Please report this as a bug.`) + } // fall back to cjs - pluginFn = requireModule(pluginName, { paths: [cwd] }) + pluginFn = requireModule(pluginPath, { paths: [cwd] }) } if (typeof pluginFn === 'function') { plugins.push(pluginFn(pluginOptions))