Ctrl K
ComunidadGuías…

vite.config.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import path from "node:path";
import { defineConfig, loadEnv } from "vite";
import vue from "@vitejs/plugin-vue";
import { VitePWA } from "vite-plugin-pwa";
import IconsResolver from 'unplugin-icons/resolver';
import Icons from 'unplugin-icons/vite';
import Components from 'unplugin-vue-components/vite';

// avnac-vue ships source files (TypeScript + Vue). Resolve through the installed
// package so Vite and TypeScript compile the same source in every environment.
const PACKAGE_AVNAC_SRC = path.resolve(__dirname, 'node_modules/@venmail/avnac-vue/src')
const PACKAGE_AVNAC_SRC_NORM = PACKAGE_AVNAC_SRC.replace(/\\/g, '/')
const avnacImportRewriter = {
  name: 'avnac-import-rewriter',
  enforce: 'pre' as const,
  transform(code: string, id: string) {
    const normalized = id.replace(/\\/g, '/')
    const isAvnac =
      normalized.includes(PACKAGE_AVNAC_SRC_NORM) ||
      normalized.includes('@venmail/avnac-vue/src/') ||
      normalized.includes('@venmail+avnac-vue')
    if (isAvnac) {
      return {
        code: code
          .replace(/(['"])#\//g, '$1@avnac/')
          .replace(/(['"])\@\//g, '$1@avnac/'),
        map: null,
      }
    }
  },
}

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), "");
  const shareBaseUrl = env.VITE_SHARE_BASE_URL || 'https://venia.cloud';

  return {
    plugins: [
      avnacImportRewriter,
      vue(),
      Components({
        dirs: [],
        resolvers: [
          IconsResolver({ prefix: 'i' }),
        ],
      }),
      Icons({
        compiler: 'vue3',
        autoInstall: false,
        scale: 1,
        defaultClass: 'i-icon',
      }),
      VitePWA({
        registerType: 'autoUpdate',
        injectRegister: 'auto',
        manifest: false,
        workbox: {
          globPatterns: [
            '**/*.{js,css,html,ico,png,svg,woff,woff2,ttf,eot,json}',
          ],
          maximumFileSizeToCacheInBytes: 15 * 1024 * 1024,
          // SPA shell fallback. The app is responsible for showing offline UI when API calls fail.
          navigateFallback: '/index.html',
          navigateFallbackDenylist: [
            /^\/api\//,
            /^\/storage\//,
            /^\/manifest\.json$/,
            /^\/sw\.js$/,
          ],
          // NOTE: We intentionally do NOT cache /api/* or /storage/* here. Those responses are
          // authenticated and user-scoped; caching them in a shared SW cache would leak data
          // across sessions on the same device. The app handles document offline storage via
          // its own local cache layer (see src/store/files.ts).
          runtimeCaching: [
            {
              urlPattern: /^https:\/\/fonts\.(?:googleapis|gstatic)\.com\/.*/i,
              handler: 'CacheFirst',
              options: {
                cacheName: 'google-fonts',
                expiration: { maxEntries: 30, maxAgeSeconds: 60 * 60 * 24 * 365 },
                cacheableResponse: { statuses: [0, 200] },
              },
            },
          ],
        },
        // Keep service worker disabled in dev to avoid HMR issues. Set to true only when testing PWA behavior.
        devOptions: {
          enabled: false,
          type: 'module',
        },
      }),
    ],
    optimizeDeps: {
      // Exclude avnac-vue source from pre-bundling; avnacImportRewriter handles #/ at serve time.
      exclude: ['@venmail/avnac-vue', '@avnac'],
      // jszip is CJS and imported by avnac-vue (which is excluded above).
      include: ['jszip'],
      esbuildOptions: {
        plugins: [
          {
            name: 'avnac-dep-scan-resolver',
            setup(build: any) {
              build.onResolve({ filter: /^[#@]\// }, (args: any) => {
                const importer = (args.importer || '').replace(/\\/g, '/')
                if (
                  importer.includes('/node_modules/@venmail/avnac-vue/src/') ||
                  importer.includes('@venmail+avnac-vue') ||
                  importer.includes(PACKAGE_AVNAC_SRC_NORM)
                ) {
                  return { external: true }
                }
              })
            },
          },
        ],
      },
    },
    server: {
      hmr: { overlay: false },
      proxy: {
        "/api": {
          target: "http://127.0.0.1:8000",
          changeOrigin: true,
          secure: false,
        },
        "/storage": {
          target: shareBaseUrl,
          changeOrigin: true,
          secure: true,
        },
      },
    },
    build: {
      chunkSizeWarningLimit: 13000,
      target: 'es2020',
      minify: 'terser',
      terserOptions: {
        compress: { keep_infinity: true, passes: 1 },
      },
      rollupOptions: {
        onwarn(warning, warn) {
          const message = warning.message || '';
          if (message.includes('is dynamically imported by') && message.includes('@venmail/avnac-vue')) {
            return;
          }
          warn(warning);
        },
        output: {
          assetFileNames(assetInfo) {
            if (assetInfo.names?.some((n: string) => n.endsWith('.mjs'))) {
              return 'assets/[name]-[hash].js';
            }
            return 'assets/[name]-[hash].[ext]';
          },
          manualChunks(id) {
            if (id.includes('node_modules/echarts') || id.includes('node_modules/zrender')) {
              return 'vendor-echarts';
            }
            if (id.includes('node_modules/mermaid') || id.includes('node_modules/@mermaid-js')) {
              return 'vendor-mermaid';
            }
            if (id.includes('node_modules/pdfjs-dist')) {
              return 'vendor-pdfjs';
            }
            if (id.includes('node_modules/prosemirror')) {
              return 'vendor-prosemirror';
            }
            if (id.includes('node_modules/dexie')) {
              return 'vendor-dexie';
            }
          },
        },
      },
    },
    define: {
      'import.meta.env.VITE_API_BASE_URL': JSON.stringify(env.VITE_API_BASE_URL),
      'import.meta.env.VITE_AUTH_URL': JSON.stringify(env.VITE_AUTH_URL),
      'import.meta.env.VITE_OAUTH_REDIRECT_URI': JSON.stringify(env.VITE_OAUTH_REDIRECT_URI),
      // The repository's deployment environments use SOCKET_BASE_URL. Expose it
      // under Vite's client-safe prefix for all collaboration clients.
      'import.meta.env.VITE_SOCKET_BASE_URL': JSON.stringify(env.VITE_SOCKET_BASE_URL || env.SOCKET_BASE_URL),
      'import.meta.env.SOCKET_BASE_URL': JSON.stringify(env.SOCKET_BASE_URL),
    },
    css: {
      preprocessorOptions: {
        scss: {
          silenceDeprecations: ['import', 'legacy-js-api', 'global-builtin'],
        },
      },
    },
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./src"),
        "@avnac": PACKAGE_AVNAC_SRC,
        "#": PACKAGE_AVNAC_SRC,
        fs: path.resolve(__dirname, './src/shims/node-empty.ts'),
        path: path.resolve(__dirname, './src/shims/node-empty.ts'),
        crypto: path.resolve(__dirname, './src/shims/node-empty.ts'),
      },
    },
  };
});