From 385caed94b579727e76b23aa9ecc006ea9f6f0d1 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Wed, 26 Nov 2025 08:30:47 -0500 Subject: [PATCH] Add Vite configuration and shared build config --- client/build-config.shared.js | 81 +++++++++++++++++++++++++++++++++++ client/vite.config.mjs | 76 ++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 client/build-config.shared.js create mode 100644 client/vite.config.mjs diff --git a/client/build-config.shared.js b/client/build-config.shared.js new file mode 100644 index 00000000000..eb0a1b576fe --- /dev/null +++ b/client/build-config.shared.js @@ -0,0 +1,81 @@ +/** + * Shared build configuration for both webpack and vite + * Single source of truth for legacy module resolution + */ +import path from "path"; +import { fileURLToPath } from "url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const scriptsBase = path.join(__dirname, "src"); +const libsBase = path.join(scriptsBase, "libs"); +const styleBase = path.join(scriptsBase, "style"); + +// Legacy exact-match aliases (webpack uses $ suffix, we store without it) +export const legacyAliases = { + // Core libraries + jquery: path.join(libsBase, "jquery.custom.js"), + jqueryVendor: path.join(libsBase, "jquery/jquery.js"), + storemodern: path.join(__dirname, "node_modules/store/dist/store.modern.js"), + + // Vue + vue: path.join(__dirname, "node_modules/vue/dist/vue.esm.js"), + + // Build config + config: path.join(scriptsBase, "config", process.env.NODE_ENV || "development") + ".js", + app: path.join(scriptsBase, "app.js"), +}; + +// Module resolution paths (webpack's resolve.modules) +export const modulePaths = [scriptsBase, "node_modules", styleBase]; + +// File extensions for resolution +export const extensions = [".ts", ".js", ".json", ".vue", ".scss"]; + +/** + * Convert to webpack format (adds $ suffix for exact matches) + */ +export function getWebpackAliases() { + const aliases = { ...legacyAliases }; + + // Add $ suffix for exact matches + const webpackAliases = {}; + for (const [key, value] of Object.entries(aliases)) { + webpackAliases[key + "$"] = value; + } + + // Add non-exact aliases + webpackAliases["@"] = scriptsBase; + + return webpackAliases; +} + +/** + * Convert to vite format (uses regex patterns) + */ +export function getViteAliases() { + const viteAliases = [ + // @ alias + { find: "@", replacement: scriptsBase }, + ]; + + // Add exact match patterns + for (const [key, value] of Object.entries(legacyAliases)) { + // Skip jquery in dev mode - handled by plugin + if (key === "jquery" && process.env.NODE_ENV === "development") { + continue; + } + + viteAliases.push({ + find: new RegExp(`^${key}$`), + replacement: path.isAbsolute(value) ? value : path.join(__dirname, value), + }); + } + + // Add prefix patterns for legacy paths + viteAliases.push( + { find: /^libs\//, replacement: libsBase + "/" }, + { find: /^ui\//, replacement: path.join(scriptsBase, "ui") + "/" } + ); + + return viteAliases; +} diff --git a/client/vite.config.mjs b/client/vite.config.mjs new file mode 100644 index 00000000000..73ca74be274 --- /dev/null +++ b/client/vite.config.mjs @@ -0,0 +1,76 @@ +import { defineConfig } from "vite"; +import vue from "@vitejs/plugin-vue2"; +import tsconfigPaths from "vite-tsconfig-paths"; +import ViteYaml from "@modyfi/vite-plugin-yaml"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { galaxyLegacyPlugin } from "./vite-plugin-webpack-aliases.js"; +import { buildMetadataPlugin } from "./vite-plugin-build-metadata.js"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineConfig({ + define: { + // Make jQuery available globally for plugins and legacy code + global: "globalThis", + // Define build system for runtime checks + __GALAXY_BUILD_SYSTEM__: JSON.stringify("vite"), + // Define build timestamp + __buildTimestamp__: JSON.stringify(new Date().toISOString()), + // Define webpack public path as a no-op for Vite + __webpack_public_path__: "undefined", + }, + plugins: [ + vue(), // Vue 2.7 support + tsconfigPaths(), // TypeScript path resolution + ViteYaml(), // YAML file support + galaxyLegacyPlugin(), // Handle legacy webpack-style imports + buildMetadataPlugin(), // Generate build metadata (replaces DumpMetaPlugin) + ], + // resolve aliases are handled by galaxyLegacyPlugin + css: { + preprocessorOptions: { + scss: { + quietDeps: true, + silenceDeprecations: ["mixed-decls", "import"], + includePaths: ["src/style", "src/style/scss", "node_modules"], + }, + }, + }, + build: { + outDir: "dist", + emptyOutDir: true, + // Generate manifest.json for production + manifest: true, + rollupOptions: { + input: { + // Entry points that will be referenced in templates + analysis: resolve(__dirname, "src/entry/analysis/index.ts"), + generic: resolve(__dirname, "src/entry/generic.js"), + }, + output: { + entryFileNames: "[name].bundled.js", + chunkFileNames: "[name]-[hash].js", + assetFileNames: "[name]-[hash].[ext]", + }, + }, + }, + server: { + port: process.env.VITE_PORT || 5173, + cors: true, + hmr: { + // Ensure HMR works correctly + protocol: "ws", + host: "localhost", + }, + // Allow Galaxy to access Vite dev server + headers: { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", + "Access-Control-Allow-Headers": "Content-Type, Authorization", + }, + }, + worker: { + format: "es", + }, +});