diff --git a/packages/pigment-css-nextjs-plugin/src/index.ts b/packages/pigment-css-nextjs-plugin/src/index.ts index 92b0ddee1dcf21..ecf7b1598687b2 100644 --- a/packages/pigment-css-nextjs-plugin/src/index.ts +++ b/packages/pigment-css-nextjs-plugin/src/index.ts @@ -1,15 +1,9 @@ import * as path from 'node:path'; import type { NextConfig } from 'next'; import { findPagesDir } from 'next/dist/lib/find-pages-dir'; -import { - webpack as webpackPlugin, - extendTheme, - type PigmentOptions as BasePigmentOptions, -} from '@pigment-css/unplugin'; +import { webpack as webpackPlugin, extendTheme, type PigmentOptions } from '@pigment-css/unplugin'; -export type PigmentOptions = BasePigmentOptions & { - asyncResolve?: (what: string) => string | null; -}; +export { type PigmentOptions }; const extractionFile = path.join( path.dirname(require.resolve('../package.json')), @@ -60,14 +54,23 @@ export function withPigment(nextConfig: NextConfig, pigmentConfig?: PigmentOptio outputCss: dev || hasAppDir || !isServer, placeholderCssFile: extractionFile, }, - asyncResolve(what) { + async asyncResolve(what: string, importer: string, stack: string[]) { + // Need to point to the react from node_modules during eval time. + // Otherwise, next makes it point to its own version of react that + // has a lot of RSC specific logic which is not actually needed. + if (what.startsWith('react') || what.startsWith('next')) { + return require.resolve(what); + } if (what === 'next/image') { return require.resolve('../next-image'); } if (what.startsWith('next/font')) { return require.resolve('../next-font'); } - return asyncResolve?.(what) ?? null; + if (asyncResolve) { + return asyncResolve(what, importer, stack); + } + return null; }, babelOptions: { ...babelOptions, diff --git a/packages/pigment-css-unplugin/src/index.ts b/packages/pigment-css-unplugin/src/index.ts index 38ef63479089ee..262577e8056808 100644 --- a/packages/pigment-css-unplugin/src/index.ts +++ b/packages/pigment-css-unplugin/src/index.ts @@ -41,6 +41,7 @@ type WebpackMeta = { }; type Meta = NextMeta | ViteMeta | WebpackMeta; +export type AsyncResolver = (what: string, importer: string, stack: string[]) => Promise; export type PigmentOptions = { theme?: Theme; @@ -49,7 +50,7 @@ export type PigmentOptions = { debug?: IFileReporterOptions | false; sourceMap?: boolean; meta?: Meta; - asyncResolve?: (what: string) => string | null; + asyncResolve?: (...args: Parameters) => Promise; transformSx?: boolean; } & Partial; @@ -62,8 +63,6 @@ function hasCorectExtension(fileName: string) { const VIRTUAL_CSS_FILE = `\0zero-runtime-styles.css`; const VIRTUAL_THEME_FILE = `\0zero-runtime-theme.js`; -type AsyncResolver = (what: string, importer: string, stack: string[]) => Promise; - function isZeroRuntimeThemeFile(fileName: string) { return fileName === VIRTUAL_CSS_FILE || fileName === VIRTUAL_THEME_FILE; } @@ -142,13 +141,11 @@ export const plugin = createUnplugin((options) => { let webpackResolver: AsyncResolver; const asyncResolve: AsyncResolver = async (what, importer, stack) => { - const result = asyncResolveOpt?.(what); + const result = await asyncResolveOpt?.(what, importer, stack); if (typeof result === 'string') { return result; } - // Use Webpack's resolver to resolve actual path but - // ignore next.js files during evaluation phase of WyW - if (webpackResolver && !what.startsWith('next')) { + if (webpackResolver) { return webpackResolver(what, importer, stack); } return asyncResolveFallback(what, importer, stack);