diff --git a/packages/pigment-css-vite-plugin/src/index.ts b/packages/pigment-css-vite-plugin/src/index.ts index a00f3cfba..5eef74db2 100644 --- a/packages/pigment-css-vite-plugin/src/index.ts +++ b/packages/pigment-css-vite-plugin/src/index.ts @@ -9,6 +9,11 @@ import { } from '@pigment-css/react/utils'; import { transformAsync } from '@babel/core'; import baseWywPluginPlugin, { type VitePluginOptions } from './vite-plugin'; +import { + VIRTUAL_CSS_FILE, + VIRTUAL_THEME_FILE, + resolvePigmentPath, +} from './utils/resolvePigmentPath'; export interface PigmentOptions extends Omit { /** @@ -25,9 +30,6 @@ type PigmentMeta = { }; }; -const VIRTUAL_CSS_FILE = `\0zero-runtime-styles.css`; -const VIRTUAL_THEME_FILE = `\0zero-runtime-theme.js`; - const extensions = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts']; function hasCorectExtension(fileName: string) { @@ -66,13 +68,8 @@ export function pigment(options: PigmentOptions) { name: 'pigment-css-theme-injection-plugin', enforce: 'pre', resolveId(source) { - if (finalTransformLibraries.some((lib) => source.includes(`${lib}/styles.css`))) { - return VIRTUAL_CSS_FILE; - } - if (finalTransformLibraries.some((lib) => source.includes(`${lib}/theme`))) { - return VIRTUAL_THEME_FILE; - } - return null; + // Vite/Rollup internally normalizes all path separators to forward slashes (/) before passing source to resolveId, regardless of the OS. + return resolvePigmentPath(source, allLibs); }, load(id) { if (id === VIRTUAL_CSS_FILE) { diff --git a/packages/pigment-css-vite-plugin/src/utils/resolvePigmentPath.ts b/packages/pigment-css-vite-plugin/src/utils/resolvePigmentPath.ts new file mode 100644 index 000000000..30738d56b --- /dev/null +++ b/packages/pigment-css-vite-plugin/src/utils/resolvePigmentPath.ts @@ -0,0 +1,26 @@ +/** + * Virtual CSS file path used for zero-runtime styles. + * @constant {string} + */ +export const VIRTUAL_CSS_FILE = `\0zero-runtime-styles.css`; +/** + * Virtual theme module path used for zero-runtime theme. + * @constant {string} + */ +export const VIRTUAL_THEME_FILE = `\0zero-runtime-theme.js`; + +/** + * Resolves import paths to virtual modules for Pigment CSS artifacts. + * @param {string} source - Original import source path + * @param {string[]} allLibs - List of library names to match against + * @returns {string | null} Virtual module path if matched, otherwise null + */ +export function resolvePigmentPath(source: string, allLibs: string[]) { + if (allLibs.some((lib) => source.includes(`${lib}/styles.css`))) { + return VIRTUAL_CSS_FILE; + } + if (allLibs.some((lib) => source.includes(`${lib}/theme`))) { + return VIRTUAL_THEME_FILE; + } + return null; +} diff --git a/packages/pigment-css-vite-plugin/tests/utils/resolvePigmentPath.test.ts b/packages/pigment-css-vite-plugin/tests/utils/resolvePigmentPath.test.ts new file mode 100644 index 000000000..60167e55d --- /dev/null +++ b/packages/pigment-css-vite-plugin/tests/utils/resolvePigmentPath.test.ts @@ -0,0 +1,43 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions */ +import { expect } from 'chai'; +import { resolvePigmentPath } from '../../src/utils/resolvePigmentPath'; + +describe('processPigmentTheme', () => { + describe('resolvePigmentPath', () => { + it('should resolve pigment styles path in Unix env', () => { + const UnixSep = '/'; + const source = '@mui/material-pigment-css/styles.css'; + const allLibs = ['@mui/material-pigment-css', '@mui/material-other']; + const finalTransformLibraries = allLibs.map((lib) => lib.split('/').join(UnixSep)); + // ✅ It works to resolve path in allLibs (Unix env) + expect(resolvePigmentPath(source, allLibs)).to.equal('\0zero-runtime-styles.css'); + // ✅ It works to resolve path in finalTransformLibraries (Unix env) + expect(resolvePigmentPath(source, finalTransformLibraries)).to.equal( + '\0zero-runtime-styles.css', + ); + }); + + it('should resolve pigment styles path in Windows env', () => { + const WindowsSep = '\\'; + const source = '@mui/material-pigment-css/styles.css'; + const allLibs = ['@mui/material-pigment-css', '@mui/material-other']; + const finalTransformLibraries = allLibs.map((lib) => lib.split('/').join(WindowsSep)); + // ✅ It works to resolve path in allLibs (Windows env) + expect(resolvePigmentPath(source, allLibs)).to.equal('\0zero-runtime-styles.css'); + // ❌ It doesn't work to resolve path in finalTransformLibraries (Windows env) + expect(resolvePigmentPath(source, finalTransformLibraries)).to.be.null; + }); + + it('should resolve pigment theme path', () => { + const source = '@mui/material-pigment-css/theme'; + const allLibs = ['@mui/material-pigment-css', '@mui/material-other']; + expect(resolvePigmentPath(source, allLibs)).to.equal('\0zero-runtime-theme.js'); + }); + + it('should not resolve other path', () => { + const source = '@mui/material-pigment-css-other/styles.css'; + const allLibs = ['@mui/material-pigment-css', '@mui/material-other']; + expect(resolvePigmentPath(source, allLibs)).to.be.null; + }); + }); +});