build: 打通 FastAPI 与 Vue 最小工程、依赖与数据库连接
后端入口、配置、Redis 与 Alembic 迁移就位;前端 Vite 工程可安装可构建。
This commit is contained in:
1 parent
fb0ddca4de
commit
2aee6286d6
167 files changed
+26082
No files matched your search
@@ -0,0 +1,153 @@
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as dotenv from 'dotenv'
|
||||
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
import { VitePWA } from 'vite-plugin-pwa'
|
||||
import { THEME_COLORS } from './src/config/themeColors'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
// Load env file based on `mode` in the current working directory.
|
||||
// When mode is 'prod' or 'dev', load .env.prod or .env.dev respectively
|
||||
let envDir = process.cwd()
|
||||
let envFile = '.env'
|
||||
|
||||
if (mode === 'prod' || mode === 'production') {
|
||||
// Manually load .env.prod for production builds. Plain `vite build`
|
||||
// (mode 'production', used by Dockerfile.frontend.prod) must see the
|
||||
// VITE_FIREBASE_* values too: src/sw.ts inlines them at build time, and
|
||||
// without them the service worker ships with push silently disabled.
|
||||
const envPath = path.resolve(envDir, '.env.prod')
|
||||
if (fs.existsSync(envPath)) {
|
||||
const envConfig = dotenv.parse(fs.readFileSync(envPath))
|
||||
// Merge with process.env
|
||||
for (const key in envConfig) {
|
||||
if (!process.env[key]) {
|
||||
process.env[key] = envConfig[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode === 'dev') {
|
||||
// Manually load .env.dev for development builds
|
||||
const envPath = path.resolve(envDir, '.env.dev')
|
||||
if (fs.existsSync(envPath)) {
|
||||
const envConfig = dotenv.parse(fs.readFileSync(envPath))
|
||||
// Merge with process.env
|
||||
for (const key in envConfig) {
|
||||
if (!process.env[key]) {
|
||||
process.env[key] = envConfig[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also load standard Vite env files
|
||||
const env = loadEnv(mode, process.cwd(), '')
|
||||
|
||||
if (command === 'build' && !(process.env.VITE_FIREBASE_API_KEY || env.VITE_FIREBASE_API_KEY)) {
|
||||
console.warn(
|
||||
'\n[pwa] VITE_FIREBASE_API_KEY is not set for this build — the service worker ' +
|
||||
'will ship WITHOUT background push support (foreground notifications still work ' +
|
||||
'via runtime config.js). Provide .env/.env.prod with VITE_FIREBASE_* to enable it.\n'
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
plugins: [
|
||||
vue({
|
||||
template: {
|
||||
compilerOptions: {
|
||||
// Treat all tags starting with 's-' as custom elements (Polaris web components)
|
||||
isCustomElement: (tag) => tag.startsWith('s-')
|
||||
}
|
||||
}
|
||||
}),
|
||||
vueJsx(),
|
||||
vueDevTools(),
|
||||
// Plugin to inject environment variables into HTML
|
||||
{
|
||||
name: 'html-transform',
|
||||
transformIndexHtml(html) {
|
||||
return html.replace(
|
||||
/<%= VITE_SHOPIFY_API_KEY %>/g,
|
||||
process.env.VITE_SHOPIFY_API_KEY || env.VITE_SHOPIFY_API_KEY || ''
|
||||
)
|
||||
}
|
||||
},
|
||||
VitePWA({
|
||||
strategies: 'injectManifest',
|
||||
srcDir: 'src',
|
||||
filename: 'sw.ts',
|
||||
// Registration is manual (src/pwa/register.ts) so the Shopify App Bridge
|
||||
// script stays the first script tag and embedded contexts never register.
|
||||
injectRegister: false,
|
||||
manifest: {
|
||||
name: 'ChatterMate',
|
||||
short_name: 'ChatterMate',
|
||||
description: 'Agent console for ChatterMate — handle customer chats anywhere.',
|
||||
start_url: '/',
|
||||
scope: '/',
|
||||
display: 'standalone',
|
||||
background_color: THEME_COLORS.dark,
|
||||
theme_color: THEME_COLORS.dark,
|
||||
icons: [
|
||||
{ src: '/pwa-192x192.png', sizes: '192x192', type: 'image/png' },
|
||||
{ src: '/pwa-512x512.png', sizes: '512x512', type: 'image/png' },
|
||||
{ src: '/pwa-maskable-512x512.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
|
||||
],
|
||||
},
|
||||
injectManifest: {
|
||||
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
|
||||
// config.js is runtime-substituted per environment (docker-entrypoint)
|
||||
// and must never be precached; webclient isn't the agent app.
|
||||
globIgnores: ['config.js', 'config.dev.js', 'webclient/**'],
|
||||
},
|
||||
devOptions: {
|
||||
enabled: false,
|
||||
},
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
headers: {
|
||||
'Service-Worker-Allowed': '/',
|
||||
},
|
||||
// Allow ngrok and other tunnel services for Shopify embedded app development
|
||||
allowedHosts: [
|
||||
'localhost',
|
||||
'.ngrok.app',
|
||||
'.ngrok.io',
|
||||
'frontendchat.ngrok.app',
|
||||
'.chattermate.chat',
|
||||
],
|
||||
},
|
||||
publicDir: 'public',
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
assetsDir: 'assets',
|
||||
chunkSizeWarningLimit: 600,
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: './index.html',
|
||||
},
|
||||
output: {
|
||||
manualChunks: {
|
||||
'vendor-vue': ['vue', 'vue-router', 'pinia'],
|
||||
'vendor-ui': ['vue3-apexcharts'],
|
||||
'vendor-utils': ['axios', 'marked'],
|
||||
'vendor-firebase': ['firebase/app', 'firebase/messaging', 'firebase/auth'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
Reference in new issue
Block a user