| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- import vue from '@vitejs/plugin-vue';
- import { resolve } from 'path';
- import { defineConfig, loadEnv, ConfigEnv } from 'vite';
- import vueSetupExtend from 'vite-plugin-vue-setup-extend';
- import compression from 'vite-plugin-compression2';
- import { buildConfig } from './src/utils/build';
- import vueJsx from '@vitejs/plugin-vue-jsx';
- import { CodeInspectorPlugin } from 'code-inspector-plugin';
- import fs from 'fs';
- import { visualizer } from 'rollup-plugin-visualizer';
- import { webUpdateNotice } from '@plugin-web-update-notification/vite';
- import vitePluginsAutoI18n, { EmptyTranslator } from 'vite-auto-i18n-plugin';
- const pathResolve = (dir: string) => {
- return resolve(__dirname, '.', dir);
- };
- const alias: Record<string, string> = {
- '/@': pathResolve('./src/'),
- 'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js',
- 'ezuikit-js': pathResolve('node_modules/ezuikit-js/ezuikit.js'),
- };
- const viteConfig = defineConfig((mode: ConfigEnv) => {
- const env = loadEnv(mode.mode, process.cwd());
- /** dev 代理目标:始终本机后端。勿用浏览器用的公网 VITE_API_URL,避免绕一圈且易配错 */
- const apiProxyTarget = env.VITE_PROXY_TARGET || 'http://127.0.0.1:5005';
- const devPort = Number(env.VITE_PORT) || 8888;
- /** 浏览器访问用公网 IP/域名;勿写入 server.hmr.host,否则 WS 会 bind 该地址,云主机 EIP 常不在网卡上 → EADDRNOTAVAIL */
- const devPublicHost = String(env.VITE_DEV_PUBLIC_HOST || '').trim();
- fs.writeFileSync('./public/config.js', `window.__env__ = ${JSON.stringify(env, null, 2)} `);
- return {
- plugins: [
- visualizer({ open: false }),
- CodeInspectorPlugin({
- bundler: 'vite',
- hotKeys: ['shiftKey'],
- }),
- vue(),
- vueJsx(),
- webUpdateNotice({
- versionType: 'build_timestamp',
- notificationConfig: {
- placement: 'topLeft',
- },
- notificationProps: {
- title: '📢 系统更新',
- description: '系统更新啦,请刷新页面!',
- buttonText: '刷新',
- dismissButtonText: '忽略',
- },
- }),
- vueSetupExtend(),
- ...(mode.command === 'build'
- ? [
- compression({
- deleteOriginalAssets: false,
- threshold: 5120,
- skipIfLargerOrEqual: true,
- }),
- ]
- : []),
- JSON.parse(env.VITE_OPEN_CDN) ? buildConfig.cdn() : null,
- vitePluginsAutoI18n({
- enabled: false,
- originLang: 'zh-cn',
- targetLangList: ['zh-hk', 'zh-tw', 'en', 'it'],
- translator: new EmptyTranslator(),
- }),
- ],
- root: process.cwd(),
- resolve: { alias },
- base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
- optimizeDeps: { exclude: ['vue-demi'] },
- server: {
- host: '0.0.0.0',
- port: env.VITE_PORT as unknown as number,
- open: JSON.parse(env.VITE_OPEN),
- ...(mode.command === 'serve' && devPublicHost
- ? { origin: `http://${devPublicHost}:${devPort}` }
- : {}),
- // VITE_HMR=false 可关热更新。公网访问时不要给 hmr.host 填 EIP(见 devPublicHost 注释)
- // 勿设 hmr.port === server.port:Vite 8 会先把 WS 占住该端口,HTTP 再监听会冲突并退到 8889,浏览器仍访问 8888 会 426
- hmr: env.VITE_HMR === 'false' ? false : true,
- // 文件监视过多时 inotify 会 ENOSPC;设 VITE_WATCH_POLLING=true 可改用轮询(略耗 CPU)
- watch:
- env.VITE_WATCH_POLLING === 'true'
- ? { usePolling: true, interval: 1500 }
- : undefined,
- proxy: {
- // 勿对 /api 开 ws:true,在部分环境下会导致普通 GET 挂起无响应
- '/api': {
- target: apiProxyTarget,
- changeOrigin: true,
- },
- '/upload': {
- target: apiProxyTarget,
- changeOrigin: true,
- },
- '/Upload': {
- target: apiProxyTarget,
- changeOrigin: true,
- },
- '/hubs': {
- target: apiProxyTarget,
- changeOrigin: true,
- ws: true,
- },
- '/schedule': {
- target: apiProxyTarget,
- changeOrigin: true,
- },
- },
- },
- build: {
- outDir: 'dist',
- chunkSizeWarningLimit: 1500,
- assetsInlineLimit: 5000, // 小于此阈值的导入或引用资源将内联为 base64 编码
- sourcemap: false, // 构建后是否生成 source map 文件
- extractComments: false, // 移除注释
- // esbuild 压缩内存占用远低于 terser;maxParallelFileOps 降低并发,便于小内存环境完成构建
- minify: 'esbuild',
- esbuild: {
- drop: mode.mode === 'production' ? ['console', 'debugger'] : [],
- },
- rollupOptions: {
- output: {
- chunkFileNames: 'assets/js/[name]-[hash].js', // 引入文件名的名称
- entryFileNames: 'assets/js/[name]-[hash].js', // 包的入口文件名称
- assetFileNames: 'assets/[ext]/[name]-[hash].[ext]', // 资源文件像 字体,图片等
- // 小内存环境构建时可去掉 manualChunks,降低 Rollup 分析内存(大机器可恢复分包策略)
- ...(process.env.VITE_LOW_MEM_BUILD === '1'
- ? {}
- : {
- manualChunks(id: string) {
- if (id.includes('node_modules')) {
- return id.toString().match(/\/node_modules\/(?!.pnpm)(?<moduleName>[^\/]*)\//)?.groups!.moduleName ?? 'vender';
- }
- },
- }),
- },
- ...(JSON.parse(env.VITE_OPEN_CDN) ? { external: buildConfig.external } : {}),
- },
- },
- css: { preprocessorOptions: { css: { charset: false }, scss: { silenceDeprecations: ['legacy-js-api', 'global-builtin', 'fs-importer-cwd', 'import'] } } },
- define: {
- __VUE_I18N_LEGACY_API__: JSON.stringify(false),
- __VUE_I18N_FULL_INSTALL__: JSON.stringify(false),
- __INTLIFY_PROD_DEVTOOLS__: JSON.stringify(false),
- __NEXT_VERSION__: JSON.stringify(process.env.npm_package_version),
- __NEXT_NAME__: JSON.stringify(process.env.npm_package_name),
- },
- };
- });
- export default viteConfig;
|