import { defineConfig } from "vite"; import symfonyPlugin from "vite-plugin-symfony"; import vue from "@vitejs/plugin-vue"; import { resolve } from "path"; import { writeFile, mkdir } from "fs/promises"; import { existsSync } from "fs"; // --- Vite configuration aggregated from per-bundle vite.config.js files --- // Import per-bundle lightweight config objects that replace former chill.webpack.config.js import ChillMain from "./src/Bundle/ChillMainBundle/vite.config.js"; import ChillPerson from "./src/Bundle/ChillPersonBundle/vite.config.js"; import ChillActivity from "./src/Bundle/ChillActivityBundle/vite.config.js"; import ChillBudget from "./src/Bundle/ChillBudgetBundle/vite.config.js"; import ChillCalendar from "./src/Bundle/ChillCalendarBundle/vite.config.js"; import ChillDocGenerator from "./src/Bundle/ChillDocGeneratorBundle/vite.config.js"; import ChillDocStore from "./src/Bundle/ChillDocStoreBundle/vite.config.js"; import ChillEvent from "./src/Bundle/ChillEventBundle/vite.config.js"; import ChillTask from "./src/Bundle/ChillTaskBundle/vite.config.js"; import ChillThirdParty from "./src/Bundle/ChillThirdPartyBundle/vite.config.js"; import ChillWopi from "./src/Bundle/ChillWopiBundle/vite.config.js"; import ChillJob from "./src/Bundle/ChillJobBundle/src/vite.config.js"; async function ensureChillAggregatedEntry(chillEntries) { // Generate a small aggregate file that imports all base chill entry files const outDir = "./assets"; if (!existsSync(outDir)) { await mkdir(outDir, { recursive: true }); } const outFile = resolve(outDir, "chill.entry.js"); const unique = Array.from(new Set(chillEntries)); const content = unique .map((p, i) => `// auto-generated import ${i}\nimport "${p.replace(/\\/g, "/")}";`) .join("\n"); await writeFile(outFile, `${content}\n`); return outFile; } export default defineConfig(async () => { // Merge per-bundle small configs const bundleConfigs = [ ChillMain, ChillPerson, ChillActivity, ChillBudget, ChillCalendar, ChillDocGenerator, ChillDocStore, ChillEvent, ChillTask, ChillThirdParty, ChillWopi, ChillJob, ]; // Aggregate chill base imports const chillBases = bundleConfigs.flatMap((c) => c.chillBase ?? []); const chillEntryPath = await ensureChillAggregatedEntry( chillBases.map((p) => resolve(__dirname, p)) ); // Merge inputs const inputs = Object.assign( {}, // Legacy root app entry if present existsSync(resolve("./assets/app.js")) ? { app: "./assets/app.js" } : {}, existsSync(resolve("./assets/app.ts")) ? { app: "./assets/app.ts" } : {}, // Per bundle inputs ...bundleConfigs.map((c) => c.inputs || {}) ); // Add the aggregated chill shared entry inputs.chill = chillEntryPath; // Merge aliases (root level + bundle level) and normalize to absolute paths const mergedAliasObj = Object.assign( { translator: resolve(__dirname, "./assets/translator"), "@symfony/ux-translator": resolve( __dirname, "./vendor/symfony/ux-translator/assets" ), }, ...bundleConfigs.map((c) => c.aliases || {}) ); // Vite/Rollup alias replacements work best with absolute paths. Convert any // string replacements to absolute paths rooted at this config file. const aliasObj = Object.fromEntries( Object.entries(mergedAliasObj).map(([key, val]) => { if (typeof val === "string") { // If already absolute (starts with "/" or a drive letter pattern), keep it. const isAbsolute = val.startsWith("/") || /^[A-Za-z]:\\/.test(val); return [key, isAbsolute ? val : resolve(__dirname, val)]; } return [key, val]; }) ); // Support legacy Sass/Webpack tilde imports like `~Alias/...` by adding // a tilded alias that points to the same location for every alias key. for (const key of Object.keys(aliasObj)) { if (!key.startsWith("~")) { const tildeKey = `~${key}`; if (!aliasObj[tildeKey]) { aliasObj[tildeKey] = aliasObj[key]; } } } return { plugins: [ vue(), symfonyPlugin(), ], resolve: { alias: aliasObj, // Allow imports without extension for Vue and TS like `.../App` or `.../Modal` extensions: [ ".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue", ], }, css: { // Forward options to sass/scss compiler to quiet dependency warnings preprocessorOptions: { scss: { quietDeps: true, silenceDeprecations: ["import"], }, sass: { quietDeps: true, silenceDeprecations: ["import"], }, }, }, server: { // ViteBundle reads Symfony env to configure devServer proxy automatically. // Keep defaults; expose HMR host for Docker if needed later. strictPort: false, }, build: { sourcemap: process.env.NODE_ENV !== "production", // Ensure Symfony looks for the manifest where Vite writes it outDir: resolve(__dirname, "public/build"), manifest: true, rollupOptions: { input: inputs, }, }, }; });