/* * Copyright 2022 Collate. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import react from '@vitejs/plugin-react'; import path from 'path'; import { defineConfig, loadEnv } from 'vite'; import checker from 'vite-plugin-checker'; import viteCompression from 'vite-plugin-compression'; import { nodePolyfills } from 'vite-plugin-node-polyfills'; import svgr from 'vite-plugin-svgr'; import tsconfigPaths from 'vite-tsconfig-paths'; export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), ''); const devServerTarget = env.VITE_DEV_SERVER_TARGET || env.DEV_SERVER_TARGET || 'http://localhost:8585/'; // Dynamically set base path from environment variable or use '/' as default const basePath = env.BASE_PATH || '/'; return { base: basePath, plugins: [ { name: 'html-transform', transformIndexHtml(html: string) { // Replace ${basePath} in all places except script src (handled by Vite's base config) return html.replace(/\$\{basePath\}/g, basePath); }, }, react(), svgr(), tsconfigPaths(), nodePolyfills({ include: ['process', 'buffer'], globals: { process: true, Buffer: true, }, }), mode === 'development' && checker({ typescript: true, eslint: { lintCommand: 'eslint "./**/*.{js,jsx,ts,tsx,json}" --ignore-pattern playwright/', }, overlay: { initialIsOpen: false, }, }), mode === 'production' && viteCompression({ algorithm: 'gzip', ext: '.gz', }), ].filter(Boolean), resolve: { alias: { process: 'process/browser', Quill: path.resolve(__dirname, 'node_modules/quill'), '@': path.resolve(__dirname, 'src'), '~antd': path.resolve(__dirname, 'node_modules/antd'), antd: path.resolve(__dirname, 'node_modules/antd'), '@deuex-solutions/react-tour': path.resolve( __dirname, 'node_modules/@deuex-solutions/react-tour/dist/reacttour.min.js' ), }, extensions: ['.ts', '.tsx', '.js', '.jsx', '.css', '.less', '.svg'], dedupe: [ 'react', 'react-dom', '@mui/material', '@mui/system', '@emotion/react', '@emotion/styled', ], }, css: { preprocessorOptions: { less: { javascriptEnabled: true, modifyVars: {}, math: 'always', paths: [ path.resolve(__dirname, 'node_modules'), path.resolve(__dirname, 'src'), path.resolve(__dirname, 'src/styles'), ], rewriteUrls: 'all', }, }, }, server: { port: 3000, open: true, proxy: { '/api/': { target: devServerTarget, changeOrigin: true, }, }, }, build: { outDir: 'dist', assetsDir: 'assets', copyPublicDir: true, sourcemap: false, minify: mode === 'production' ? 'esbuild' : false, rollupOptions: { output: { manualChunks: { 'react-vendor': ['react', 'react-dom', 'react-router-dom'], 'antd-vendor': ['antd', '@ant-design/icons'], 'editor-vendor': [ '@tiptap/react', '@tiptap/starter-kit', '@tiptap/extension-link', ], 'chart-vendor': ['recharts', 'reactflow'], }, assetFileNames: (assetInfo) => { const fileName = assetInfo.name || ''; const info = fileName.split('.'); const ext = info[info.length - 1]; if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(ext)) { return `images/[name]-[hash][extname]`; } return `assets/[name]-[hash][extname]`; }, }, }, }, optimizeDeps: { include: [ 'antlr4', '@azure/msal-browser', '@azure/msal-react', 'codemirror', '@deuex-solutions/react-tour', ], }, define: { 'process.env.NODE_ENV': JSON.stringify(mode), global: 'globalThis', }, }; });