feat(web): add standalone Web Vite build configuration

Phase 3A.2: Create vite.web.config.mts for building the CLI serve
Web SPA independently from the Electron build pipeline.

- __IS_ELECTRON__ = false, __IS_BROWSER_STANDALONE__ = false
- Output to dist-web/ (gitignored)
- Dev proxy: /_web and /api -> localhost:3400 (chatlab serve)
- Resolve aliases for @electron/shared and @electron/preload
  (type-only imports, erased at build time)
- npm scripts: dev:web, build:web
- Same manualChunks strategy as Electron renderer build
This commit is contained in:
digua committed 2026-05-13 19:56:14 +08:00
1 parent 086bd882a7
commit 17855858d7
3 files changed
+76

No files matched your search

+1
View File
@@ -17,6 +17,7 @@ error-log-*.txt
# Project
dist/
dist-web/
packages/server/native/
.history/
out
+2
View File
@@ -28,6 +28,8 @@
"build:mac": "pnpm run build && electron-builder --mac --config electron-builder.yml -p never",
"build:win": "pnpm run build && electron-builder --win --config electron-builder.yml -p never",
"build:linux": "pnpm run build && electron-builder --linux --config electron-builder.yml -p never",
"dev:web": "vite --config vite.web.config.mts",
"build:web": "vite build --config vite.web.config.mts",
"type-check:web": "vue-tsc --noEmit -p tsconfig.web.json",
"type-check:node": "tsc --noEmit -p tsconfig.node.json",
"type-check:all": "pnpm run type-check:web && pnpm run type-check:node",
+73
View File
@@ -0,0 +1,73 @@
/**
* Web 版 Vite 构建配置
*
* 用于构建 CLI serve Web 的 SPA 前端(不含 Electron 依赖)。
* 输出到 dist-web/,由 chatlab serve 托管。
*
* 与 Electron renderer 构建的关键区别:
* - __IS_ELECTRON__ = false(使用 FetchAdapter 而非 window.chatApi)
* - 不包含 electron/preload 和 electron/main
* - 输出目录独立(dist-web/ vs out/renderer/)
*/
import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
root: 'src/',
base: '/',
resolve: {
alias: {
'@': resolve(__dirname, 'src/'),
'~': resolve(__dirname, 'src/'),
'@openchatlab': resolve(__dirname, 'packages'),
'@electron/shared': resolve(__dirname, 'electron/shared'),
'@electron/preload': resolve(__dirname, 'electron/preload'),
},
},
define: {
__IS_ELECTRON__: JSON.stringify(false),
__IS_BROWSER_STANDALONE__: JSON.stringify(false),
},
plugins: [
vue(),
ui({
ui: {
colors: {
primary: 'pink',
neutral: 'zinc',
},
},
}),
],
build: {
outDir: resolve(__dirname, 'dist-web'),
emptyOutDir: true,
sourcemap: false,
rollupOptions: {
input: {
index: resolve(__dirname, 'src/index.html'),
},
output: {
manualChunks(id) {
if (id.includes('node_modules/echarts-wordcloud')) return 'vendor-echarts-wordcloud'
if (id.includes('node_modules/zrender')) return 'vendor-zrender'
if (id.includes('node_modules/echarts')) return 'vendor-echarts'
if (id.includes('node_modules/@nuxt/ui')) return 'vendor-nuxt-ui'
if (id.includes('node_modules/reka-ui')) return 'vendor-reka-ui'
if (id.includes('node_modules/@zumer/snapdom')) return 'vendor-snapdom'
return undefined
},
},
},
},
server: {
port: 3401,
proxy: {
'/_web': 'http://localhost:3400',
'/api': 'http://localhost:3400',
},
},
})