Files
crewli/apps/app/vite.config.ts
bert.hausmans 714abd7178 feat(router): mount pages-v2 at /v2/* with v2- name prefix
Adds a second routesFolder (src/pages-v2 -> /v2/) and extends
getRouteName so v2 routes get a v2- NAME prefix, preventing collisions
with same-named v1 pages. getPascalCaseRouteName already folds the v2/
URL segment into the base name, so the leading v2- is stripped before
v2RouteName re-adds the canonical prefix (avoids v2-v2-dashboard).
Includes the regenerated typed-router.d.ts and a boot-proof
pages-v2/dashboard.vue placeholder.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:30:33 +02:00

180 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { fileURLToPath } from 'node:url'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import {
VueRouterAutoImports,
getPascalCaseRouteName,
} from 'unplugin-vue-router'
import VueRouter from 'unplugin-vue-router/vite'
import { defineConfig } from 'vite'
import VueDevTools from 'vite-plugin-vue-devtools'
import MetaLayouts from 'vite-plugin-vue-meta-layouts'
import vuetify from 'vite-plugin-vuetify'
import tailwindcss from '@tailwindcss/vite'
import svgLoader from 'vite-svg-loader'
import { v2RouteName } from './src/plugins/1.router/v2RouteName'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
// Docs: https://github.com/posva/unplugin-vue-router
// This plugin should be placed before vue plugin
VueRouter({
// Parallel /v2/* tree (RFC-WS-GUI-REDESIGN AD-G1). The second
// routesFolder prefixes every v2 URL with /v2/; v2RouteName then
// prefixes the route NAME with `v2-` so file-name twins across
// pages/ and pages-v2/ cannot collide. Reverted at final cutover.
routesFolder: [
{ src: 'src/pages' },
{ src: 'src/pages-v2', path: 'v2/' },
],
getRouteName: routeNode => {
// Convert pascal case to kebab case
const raw = getPascalCaseRouteName(routeNode)
.replace(/([a-z\d])([A-Z])/g, '$1-$2')
.toLowerCase()
// Defensive path read: unplugin-vue-router 0.8.8 TreeNode exposes
// `.fullPath`; fall back to `.value.path` then '' so a future
// plugin bump can't silently drop the v2- prefix. Step 5 below
// empirically verifies the emitted name.
const nodePath
= (routeNode.fullPath
?? routeNode.value?.path
?? '') as string
// getPascalCaseRouteName includes the 'v2' segment from the URL
// path prefix set by routesFolder (e.g. 'v2/dashboard' → 'v2-dashboard').
// Strip that prefix before v2RouteName re-adds the canonical `v2-`
// so we get 'v2-dashboard' not 'v2-v2-dashboard'.
const isV2
= nodePath === '/v2'
|| nodePath === 'v2'
|| nodePath.startsWith('/v2/')
|| nodePath.startsWith('v2/')
const base = isV2 && raw.startsWith('v2-') ? raw.slice(3) : raw
return v2RouteName(base, nodePath)
},
}),
vue(),
VueDevTools(),
vueJsx(),
// Tailwind v4 (F3 — parallel-mode with Vuetify until F6). Placed after
// vue() so it sees compiled template content; placed before vuetify()
// so Vuetify's SCSS pipeline runs unimpeded.
tailwindcss(),
// Docs: https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin
vuetify({
styles: {
// Absolute URL so resolution does not depend on process cwd (fixes common SASS 404s).
configFile: fileURLToPath(
new URL('./src/styles/settings.scss', import.meta.url),
),
},
}),
// Docs: https://github.com/dishait/vite-plugin-vue-meta-layouts?tab=readme-ov-file
MetaLayouts({
target: './src/layouts',
defaultLayout: 'default',
}),
// Docs: https://github.com/antfu/unplugin-vue-components#unplugin-vue-components
Components({
dirs: ['src/@core/components', 'src/views/demos', 'src/components'],
dts: true,
resolvers: [
componentName => {
// Auto import `VueApexCharts`
if (componentName === 'VueApexCharts') {
return {
name: 'default',
from: 'vue3-apexcharts',
as: 'VueApexCharts',
}
}
},
],
}),
// Docs: https://github.com/antfu/unplugin-auto-import#unplugin-auto-import
AutoImport({
imports: [
'vue',
VueRouterAutoImports,
'@vueuse/core',
'@vueuse/math',
'vue-i18n',
'pinia',
],
dirs: [
'./src/@core/utils',
'./src/@core/composable/',
'./src/composables/',
'./src/utils/',
'./src/plugins/*/composables/*',
],
vueTemplate: true,
// Disabled to avoid confusion & accidental usage
ignore: ['useCookies', 'useStorage'],
}),
svgLoader(),
],
define: { 'process.env': {} },
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'@themeConfig': fileURLToPath(
new URL('./themeConfig.ts', import.meta.url),
),
'@core': fileURLToPath(new URL('./src/@core', import.meta.url)),
'@layouts': fileURLToPath(new URL('./src/@layouts', import.meta.url)),
'@images': fileURLToPath(
new URL('./src/assets/images/', import.meta.url),
),
'@styles': fileURLToPath(
new URL('./src/assets/styles/', import.meta.url),
),
'@configured-variables': fileURLToPath(
new URL(
'./src/assets/styles/variables/_template.scss',
import.meta.url,
),
),
},
},
server: {
port: 5174,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
},
},
warmup: {
clientFiles: ['./src/pages/**/*.vue', './src/components/**/*.vue'],
},
},
build: {
chunkSizeWarningLimit: 5000,
// RFC-WS-7 §3.5 — sourcemaps generated at build, uploaded to GlitchTip
// by deploy.sh, then `find dist -name '*.map' -delete` strips them
// before nginx serves dist/. No public-mapped sources on production.
sourcemap: true,
},
optimizeDeps: {
exclude: ['vuetify'],
entries: ['./src/**/*.vue'],
force: true,
},
})