Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/vite.config.ts
T

100 lines
3.8 KiB
TypeScript

import { reactRouter } from "@react-router/dev/vite";
import { sentryVitePlugin } from "@sentry/vite-plugin";
import tailwindcss from "@tailwindcss/vite";
import { visualizer } from "rollup-plugin-visualizer";
import { defineConfig, type PluginOption } from "vite";
import { envOnlyMacros } from "vite-env-only";
import tsconfigPaths from "vite-tsconfig-paths";
import { resolveAssetBase } from "./app/utils/build/assetCdnBase";
import { shouldSuppressBuildWarning } from "./app/utils/build/buildWarningTriage";
import { getManualChunkName } from "./app/utils/build/manualChunks";
// Bundle visualizer (#71) — opt-in via ANALYZE_BUNDLE=true so the production
// build keeps its current footprint. Outputs an interactive treemap to
// apps/web/build/stats.html that includes both raw and gzip sizes per chunk.
// See docs/architecture/bundle-budgets.md for the inspection workflow.
const visualizerPlugin: PluginOption[] =
process.env.ANALYZE_BUNDLE === "true"
? [
visualizer({
filename: "build/stats.html",
template: "treemap",
gzipSize: true,
brotliSize: true,
open: false,
emitFile: false,
}) as PluginOption,
]
: [];
// Source-map generation is opt-in so bundle-budget and local production builds
// do not spend time writing artifacts that only the Sentry release path needs.
// CI quality builds set TOOLCTRL_BUILD_SOURCEMAPS=1 before uploading the
// client maps as an artifact for the reusable Sentry release job.
const buildSourcemapsEnabled = process.env.TOOLCTRL_BUILD_SOURCEMAPS === "1";
// Source-map upload is gated on both SENTRY_AUTH_TOKEN and source-map
// generation, so local builds without a token build successfully and tokened
// builds do not try to upload maps unless the release lane explicitly opted in.
// The plugin is added in the dedicated CI/production release path (see
// docs/improvement-plan/02-observability/sentry-wiring-web.md, Step 9).
const sentryPlugin: PluginOption[] = process.env.SENTRY_AUTH_TOKEN && buildSourcemapsEnabled
? [
sentryVitePlugin({
authToken: process.env.SENTRY_AUTH_TOKEN,
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT ?? "boilerplate-web",
release: process.env.SENTRY_RELEASE ? { name: process.env.SENTRY_RELEASE } : undefined,
sourcemaps: {
assets: "./build/**",
filesToDeleteAfterUpload: "./build/**/*.map",
},
// Telemetry off — we self-host and never want to phone home.
telemetry: false,
}),
]
: [];
export default defineConfig(({ mode }) => ({
// Asset CDN base — when ASSET_CDN_URL is set the production build emits
// asset URLs prefixed with the CDN origin (e.g. https://cdn.example.com/assets/app-3f4a1b.js).
// Local dev intentionally ignores the var so the Vite dev server keeps serving from `/`.
// See docs/improvement-plan/03-scaling-infrastructure/asset-cdn.md and docs/ops/asset-cdn.md.
base: resolveAssetBase(process.env, mode),
resolve: {
alias: {
"@toolctrl/queue/runtime": "/dev/null",
},
},
server: { port: 3000 },
plugins: [envOnlyMacros(), tailwindcss(), reactRouter(), tsconfigPaths(), ...sentryPlugin, ...visualizerPlugin],
ssr: {
noExternal: ["minimatch"],
},
optimizeDeps: {
esbuildOptions: {
target: "esnext",
},
},
build: {
target: "esnext",
chunkSizeWarningLimit: 1800,
// Opt-in for Sentry release lanes; bundle-budget and local production
// builds keep this off for faster builds and smaller temporary output.
sourcemap: buildSourcemapsEnabled,
rollupOptions: {
output: {
manualChunks: getManualChunkName,
},
onwarn(warning, defaultHandler) {
if (shouldSuppressBuildWarning(warning)) {
return;
}
defaultHandler(warning);
},
},
},
}));