Files
yunrui_asset/frontend/vite.config.mjs
T
zhang96110 dc20bdba1f fix: 修复14个中等问题(安全+稳定性)
后端安全修复:
- devices.js: page/pageSize parseInt+范围限制、CSV导入path.basename防路径遍历
- tickets.js: CSV导出收集所有metadata key、评价限制completed状态
- users.js: 重置密码加权限检查(仅管理员或本人)
- systemSettings.js: Boolean改显式判断(修复false存储为true)
- inventory.js: 空数组Array.isArray检查(修复无法清空目标机房)
- statistics.js: 在线率改用runningDevices计算
- operationLogs.js: DATE()改strftime兼容SQLite
- devicePorts.js: 端口更新白名单过滤(防修改portId/deviceId)
- server.js: 生产环境禁用sync alter

前端修复:
- api/index.js: 401优先React Router导航(保留SPA状态)
- Scene.jsx: useFrame仅target变化时更新(减少不必要矩阵计算)
- vite.config.mjs: 移除Vue插件残留(unplugin-vue-components)
2026-04-02 03:10:06 +00:00

91 lines
2.3 KiB
JavaScript

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 从配置文件或环境变量获取端口
const getFrontendPort = () => {
// 优先级:环境变量 > 配置文件 > 默认值
if (process.env.FRONTEND_PORT) {
return parseInt(process.env.FRONTEND_PORT, 10);
}
// 尝试读取配置文件
const configPath = path.resolve(__dirname, '.frontend-port');
if (fs.existsSync(configPath)) {
try {
const port = parseInt(fs.readFileSync(configPath, 'utf-8').trim(), 10);
if (!isNaN(port) && port > 0 && port < 65536) {
return port;
}
} catch (e) {
console.warn('读取前端端口配置文件失败,使用默认端口 3000');
}
}
return 3000;
};
const port = getFrontendPort();
export default defineConfig({
plugins: [
react(),
],
assetsInclude: ['**/*.hdr', '**/*.woff2'],
server: {
host: '0.0.0.0',
port: port,
proxy: {
'/api/backup/restore-progress': {
target: 'http://localhost:8000',
changeOrigin: true,
configure: (proxy, _options) => {
proxy.on('proxyReq', (proxyReq, req, _res) => {
proxyReq.setHeader('Connection', 'keep-alive');
});
}
},
'/api': {
target: 'http://localhost:8000',
changeOrigin: true
},
'/uploads': {
target: 'http://localhost:8000',
changeOrigin: true
}
}
},
build: {
outDir: 'dist',
sourcemap: false,
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
rollupOptions: {
output: {
manualChunks: {
'vendor': ['react', 'react-dom', 'react-router-dom'],
'charts': ['axios', 'dayjs'],
'three': ['three', '@react-three/fiber', '@react-three/drei']
},
chunkFileNames: 'js/[name]-[hash].js',
entryFileNames: 'js/[name]-[hash].js',
assetFileNames: '[ext]/[name]-[hash].[ext]',
compact: true
}
}
},
optimizeDeps: {
include: ['axios', 'react-router-dom']
}
});