305 lines
8.9 KiB
JavaScript
305 lines
8.9 KiB
JavaScript
/* eslint-disable */
|
|
import { sentryVitePlugin } from "@sentry/vite-plugin";
|
|
import react from "@vitejs/plugin-react";
|
|
import chalk from "chalk";
|
|
import * as child from "child_process";
|
|
import { promises as fsPromises } from "fs";
|
|
import { createLogger, defineConfig } from "vite";
|
|
import { ViteEjsPlugin } from "vite-plugin-ejs";
|
|
import eslint from "vite-plugin-eslint";
|
|
import { VitePWA } from "vite-plugin-pwa";
|
|
import InstanceRenderManager from "./src/utils/instanceRenderMgr";
|
|
import browserslist from "browserslist";
|
|
import { browserslistToTargets } from "lightningcss";
|
|
import { fileURLToPath } from "url";
|
|
import { dirname, resolve } from "path";
|
|
|
|
process.env.VITE_APP_GIT_SHA_DATE = new Date().toLocaleString("en-US", { timeZone: "America/Los_Angeles" });
|
|
const commitHash = child.execSync("git rev-parse HEAD").toString().trimEnd();
|
|
process.env.VITE_GIT_COMMIT_HASH = commitHash;
|
|
|
|
// Resolve browserslist from package.json and map to Lightning CSS targets
|
|
const lightningCssTargets = browserslistToTargets(
|
|
browserslist(undefined, {
|
|
path: process.cwd(),
|
|
env: process.env.NODE_ENV === "production" ? "production" : "development"
|
|
})
|
|
);
|
|
|
|
const pstFormatter = new Intl.DateTimeFormat("en-CA", {
|
|
timeZone: "America/Los_Angeles",
|
|
year: "numeric",
|
|
month: "2-digit",
|
|
day: "2-digit"
|
|
});
|
|
const currentDatePST = pstFormatter.format(new Date());
|
|
|
|
const getFormattedTimestamp = () =>
|
|
new Date().toLocaleTimeString("en-US", { hour12: true }).replace("AM", "a.m.").replace("PM", "p.m.");
|
|
|
|
export const logger = createLogger("info", { allowClearScreen: false });
|
|
|
|
// Read HTTPS certs once (used by both server + preview)
|
|
const httpsCerts = {
|
|
key: await fsPromises.readFile("../certs/key.pem"),
|
|
cert: await fsPromises.readFile("../certs/cert.pem")
|
|
};
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
export default defineConfig(({ command, mode }) => {
|
|
// React Compiler is always enabled for production/test builds
|
|
// In dev mode, it's enabled by default but can be disabled with VITE_DISABLE_COMPILER_IN_DEV=true
|
|
const isBuild = command === "build";
|
|
const isTestBuild =
|
|
mode === "test" || process.env.VITE_APP_IS_TEST === "true" || process.env.VITE_APP_IS_TEST === "1";
|
|
|
|
const enableReactCompiler =
|
|
(isBuild && (mode === "production" || isTestBuild)) || // Always enable for prod/test builds
|
|
process.env?.VITE_DISABLE_COMPILER_IN_DEV !== "true"; // In dev, enable unless explicitly disabled
|
|
|
|
logger.info(
|
|
enableReactCompiler ? chalk.green.bold("React Compiler enabled") : chalk.yellow.bold("React Compiler disabled")
|
|
);
|
|
|
|
return {
|
|
base: "/",
|
|
resolve: {
|
|
dedupe: ["styled-components", "react", "react-dom"],
|
|
alias: {
|
|
// Force all styled-components imports to resolve to the same location (absolute path)
|
|
"styled-components": resolve(__dirname, "node_modules/styled-components/dist/styled-components.browser.esm.js")
|
|
}
|
|
},
|
|
plugins: [
|
|
ViteEjsPlugin((viteConfig) => ({ env: viteConfig.env })),
|
|
|
|
// PWA only for production builds (faster dev)
|
|
VitePWA({
|
|
apply: "build",
|
|
injectRegister: "auto",
|
|
registerType: "prompt",
|
|
workbox: {
|
|
navigateFallbackDenylist: [/^\/api\//] // prevent caching API routes
|
|
},
|
|
manifest: {
|
|
short_name: InstanceRenderManager({
|
|
instance: process.env.VITE_APP_INSTANCE,
|
|
imex: "ImEX Online",
|
|
rome: "Rome Online"
|
|
}),
|
|
name: InstanceRenderManager({
|
|
instance: process.env.VITE_APP_INSTANCE,
|
|
imex: "ImEX Online",
|
|
rome: "Rome Online"
|
|
}),
|
|
description: "The ultimate bodyshop management system.",
|
|
icons: [
|
|
{
|
|
src: InstanceRenderManager({
|
|
instance: process.env.VITE_APP_INSTANCE,
|
|
imex: "favicon.png",
|
|
rome: "ro-favicon.png"
|
|
}),
|
|
sizes: "64x64 32x32 24x24 16x16",
|
|
type: "image/x-icon"
|
|
},
|
|
{
|
|
src: InstanceRenderManager({
|
|
instance: process.env.VITE_APP_INSTANCE,
|
|
imex: "logo192.png",
|
|
rome: "logo192.png"
|
|
}),
|
|
type: "image/png",
|
|
sizes: "192x192"
|
|
},
|
|
{
|
|
src: InstanceRenderManager({
|
|
instance: process.env.VITE_APP_INSTANCE,
|
|
imex: "logo512.png",
|
|
rome: "ro-favicon.png"
|
|
}),
|
|
type: "image/png",
|
|
sizes: "512x512"
|
|
}
|
|
],
|
|
theme_color: InstanceRenderManager({
|
|
instance: process.env.VITE_APP_INSTANCE,
|
|
imex: "#1890ff",
|
|
rome: "#fff"
|
|
}),
|
|
background_color: "#fff",
|
|
gcm_sender_id: "103953800507"
|
|
}
|
|
}),
|
|
|
|
react(
|
|
enableReactCompiler
|
|
? {
|
|
babel: {
|
|
plugins: [["babel-plugin-react-compiler"]]
|
|
}
|
|
}
|
|
: undefined
|
|
),
|
|
|
|
eslint(),
|
|
|
|
// Sentry only for production builds (no dev overhead)
|
|
sentryVitePlugin({
|
|
apply: "build",
|
|
org: "imex",
|
|
reactComponentAnnotation: { enabled: true },
|
|
release: {
|
|
name: `${process.env.VITE_APP_IS_TEST ? "test" : "production"}-${currentDatePST}-${commitHash}`.trim()
|
|
},
|
|
project: InstanceRenderManager({
|
|
instance: process.env.VITE_APP_INSTANCE,
|
|
imex: "imexonline",
|
|
rome: "rome-online"
|
|
})
|
|
})
|
|
],
|
|
|
|
define: {
|
|
APP_VERSION: JSON.stringify(process.env.npm_package_version),
|
|
__COMMIT_HASH__: JSON.stringify(commitHash)
|
|
},
|
|
|
|
server: {
|
|
host: true,
|
|
port: 3000,
|
|
open: true,
|
|
proxy: {
|
|
"/ws": {
|
|
target: "http://localhost:4000",
|
|
secure: false,
|
|
ws: true
|
|
},
|
|
"/wss": {
|
|
target: "http://localhost:4000",
|
|
secure: false,
|
|
ws: true
|
|
},
|
|
"/api": {
|
|
target: "http://localhost:4000",
|
|
changeOrigin: true,
|
|
secure: false,
|
|
ws: false,
|
|
rewrite: (path) => {
|
|
const replacedValue = path.replace(/^\/api/, "");
|
|
logger.info(
|
|
`${chalk.grey.bold(getFormattedTimestamp())} ${chalk.cyan.bold("[vite]")} ${chalk.green.bold("[API]")} ${chalk.blue(replacedValue)}`
|
|
);
|
|
return replacedValue;
|
|
}
|
|
}
|
|
},
|
|
https: httpsCerts
|
|
},
|
|
|
|
preview: {
|
|
port: 6000,
|
|
host: true,
|
|
open: true,
|
|
https: httpsCerts,
|
|
proxy: {
|
|
"/ws": {
|
|
target: "http://localhost:4000",
|
|
rewriteWsOrigin: true,
|
|
secure: false,
|
|
ws: true
|
|
},
|
|
"/wss": {
|
|
target: "http://localhost:4000",
|
|
rewriteWsOrigin: true,
|
|
secure: false,
|
|
ws: true
|
|
},
|
|
"/api": {
|
|
target: "http://localhost:4000",
|
|
changeOrigin: true,
|
|
secure: false,
|
|
ws: false
|
|
}
|
|
}
|
|
},
|
|
|
|
build: {
|
|
sourcemap: true,
|
|
rollupOptions: {
|
|
output: {
|
|
manualChunks: {
|
|
antd: ["antd"],
|
|
"react-redux": ["react-redux"],
|
|
redux: ["redux"],
|
|
lodash: ["lodash"],
|
|
"@sentry/react": ["@sentry/react"],
|
|
"@splitsoftware/splitio-react": ["@splitsoftware/splitio-react"],
|
|
logrocket: ["logrocket"],
|
|
firebase: [
|
|
"@firebase/analytics",
|
|
"@firebase/app",
|
|
"@firebase/firestore",
|
|
"@firebase/auth",
|
|
"@firebase/messaging"
|
|
],
|
|
markerjs2: ["markerjs2"],
|
|
"@apollo/client": ["@apollo/client"],
|
|
"libphonenumber-js": ["libphonenumber-js"],
|
|
recharts: ["recharts"]
|
|
}
|
|
}
|
|
},
|
|
|
|
cssMinify: "lightningcss"
|
|
},
|
|
|
|
// Strip console/debugger in prod to shrink bundles
|
|
esbuild: {
|
|
// drop: mode === "production" ? ["console", "debugger"] : [],
|
|
legalComments: "none" // Remove license comments in production
|
|
},
|
|
|
|
optimizeDeps: {
|
|
include: [
|
|
"react",
|
|
"react-dom",
|
|
"antd",
|
|
"lodash",
|
|
"@sentry/react",
|
|
"@apollo/client",
|
|
"@reduxjs/toolkit",
|
|
"axios",
|
|
"react-router-dom",
|
|
"dayjs",
|
|
"redux",
|
|
"react-redux",
|
|
"@firebase/app",
|
|
"@firebase/analytics",
|
|
"@firebase/firestore",
|
|
"@firebase/auth",
|
|
"@firebase/messaging",
|
|
"@firebase/util",
|
|
"styled-components"
|
|
],
|
|
esbuildOptions: {
|
|
loader: { ".jsx": "jsx", ".tsx": "tsx" }
|
|
},
|
|
// Force styled-components to be pre-bundled and deduplicated
|
|
force: mode === "development"
|
|
},
|
|
|
|
css: {
|
|
transformer: "lightningcss",
|
|
lightningcss: {
|
|
targets: lightningCssTargets
|
|
},
|
|
preprocessorOptions: {
|
|
scss: { quietDeps: true }
|
|
}
|
|
}
|
|
};
|
|
});
|