diff --git a/features/platform-content-tools/frontend-dev/vite.config.ts b/features/platform-content-tools/frontend-dev/vite.config.ts index 5d743b9b1..1f1d12104 100644 --- a/features/platform-content-tools/frontend-dev/vite.config.ts +++ b/features/platform-content-tools/frontend-dev/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import path from 'path'; +import fs from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { versionPlugin } from '../../../@packages/@utils/vite-version-plugin/src'; @@ -57,15 +58,66 @@ const ignoreStyledDtsPlugin = { } }; +// Plugin to resolve @/ imports based on importer's feature location +const featureAliasPlugin = { + name: 'feature-alias-resolver', + resolveId(source: string, importer: string | undefined) { + if (!source.startsWith('@/') || !importer) return null; + + // Map of feature paths to their src directories + const featureMap: Record = { + 'seo/frontend-admin': path.resolve(__dirname, '../../seo/frontend-admin/src'), + 'truth-validation/frontend-admin': path.resolve(__dirname, '../../truth-validation/frontend-admin/src'), + }; + + // Find which feature the importer belongs to + let srcPath = path.resolve(__dirname, './src'); // default + for (const [featurePath, featureSrcPath] of Object.entries(featureMap)) { + if (importer.includes(featurePath)) { + srcPath = featureSrcPath; + break; + } + } + + const relativePath = source.slice(2); // Remove @/ + let resolvedPath = path.resolve(srcPath, relativePath); + + // Check if it's a directory and look for index file + try { + const stat = fs.statSync(resolvedPath); + if (stat.isDirectory()) { + // Try index.tsx first, then index.ts + for (const ext of ['.tsx', '.ts', '.js']) { + const indexPath = path.join(resolvedPath, `index${ext}`); + if (fs.existsSync(indexPath)) { + return indexPath; + } + } + } + } catch { + // Path doesn't exist yet, try adding extensions + for (const ext of ['.tsx', '.ts', '.js']) { + const withExt = resolvedPath + ext; + if (fs.existsSync(withExt)) { + return withExt; + } + } + } + + return resolvedPath; + } +}; + export default defineConfig({ plugins: [ + featureAliasPlugin, react(), versionPlugin({ appName: 'Platform Content Tools' }), ignoreStyledDtsPlugin, ], resolve: { alias: { - '@': path.resolve(__dirname, './src'), + // @/ is handled by featureAliasPlugin '@features': path.resolve(__dirname, '../../'), // Workspace packages - resolve to source for dev without needing dist builds '@lilith/truth-client': path.resolve(__dirname, '../../truth-validation/client/typescript/src'),