Ctrl K
ComunidadGuías…

front/vite.config.mjs

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

Archivo original ↗Preguntar a KiBot
import { defineConfig, loadEnv, transformWithOxc } from 'vite';
import preact from '@preact/preset-vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import { patchCssModules } from 'vite-css-modules';
import { readFileSync } from 'fs';
import { dirname, resolve } from 'path';
import { fileURLToPath } from 'url';
import { preactCliCssModules } from './vite-plugins/preact-cli-css-modules.js';
import { preactAsyncRoutes, getRouteChunkName } from './vite-plugins/preact-async-routes.js';
import { serverCommonjsInterop } from './vite-plugins/server-commonjs-interop.js';

const FRONT_ROOT = dirname(fileURLToPath(import.meta.url));
const SRC_ROOT = resolve(FRONT_ROOT, 'src');

// The released Gladys version, from the same root package.json field the
// server reads at startup (server/lib/system/system.init.js). The hosted
// Gladys Plus front is built from the release tag, so baking it in lets the
// front detect an instance lagging behind (see utils/instanceVersion.js).
const GLADYS_VERSION = JSON.parse(readFileSync(resolve(FRONT_ROOT, '../package.json'), 'utf8')).version;

function treatJsFilesAsJsx() {
  return {
    name: 'treat-js-files-as-jsx',
    enforce: 'pre',
    async transform(code, id) {
      if (!/\/src\/.*\.js($|\?)/.test(id)) {
        return null;
      }

      return transformWithOxc(code, id, {
        lang: 'jsx',
        jsx: {
          runtime: 'automatic',
          importSource: 'preact'
        }
      });
    }
  };
}

const ENV_KEYS = [
  'GLADYS_GATEWAY_API_URL',
  'LOCAL_API_URL',
  'DEMO_MODE',
  'DEMO_REQUEST_TIME',
  'WEBSOCKET_URL',
  'GATEWAY_MODE',
  'STRIPE_API_KEY',
  'ENEDIS_FORCE_USAGE_POINTS'
];

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');

  const processEnvDefine = ENV_KEYS.reduce((definitions, key) => {
    // JSON.stringify(undefined) is not a string: replace unset variables with
    // the literal `undefined` so `process.env.X` expressions stay valid code.
    definitions[`process.env.${key}`] = env[key] === undefined ? 'undefined' : JSON.stringify(env[key]);
    return definitions;
  }, {});

  const plugins = [
    serverCommonjsInterop(),
    patchCssModules({ exportMode: 'both' }),
    preactAsyncRoutes({ srcRoot: SRC_ROOT }),
    treatJsFilesAsJsx(),
    preactCliCssModules(),
    preact(),
    viteStaticCopy({
      targets: [
        // The directory structure is preserved: strip `src/assets/` so files land
        // in build/assets/<sub-folder>/ (not build/assets/src/assets/).
        { src: 'src/assets/**/*', dest: 'assets', rename: { stripBase: 2 } },
        { src: 'src/manifest.json', dest: '.', rename: { stripBase: true } }
      ]
    })
  ];

  return {
    plugins,
    resolve: {
      alias: {
        react: 'preact/compat',
        'react-dom/test-utils': 'preact/test-utils',
        'react-dom': 'preact/compat',
        '/assets': resolve(FRONT_ROOT, 'src/assets')
      }
    },
    define: {
      'process.env.NODE_ENV': JSON.stringify(mode === 'production' ? 'production' : 'development'),
      'process.env.GLADYS_FRONT_VERSION': JSON.stringify(GLADYS_VERSION),
      ...processEnvDefine
    },
    server: {
      port: 1444,
      strictPort: true,
      // preact-cli exposed the dev server on the network (0.0.0.0): keep that
      // behavior so the dev front stays reachable from another device (tablet,
      // phone) or through WSL2 port forwarding. Vite only binds localhost by default.
      host: true,
      // The server advertises a configurable name on the local network with mDNS,
      // so any ".local" host must be allowed, not just the default one.
      allowedHosts: ['.local'],
      fs: {
        allow: ['..']
      },
      // Transform the whole app on startup instead of on first request:
      // the app is one large SPA and every page load pulls in most of it.
      warmup: {
        clientFiles: ['./src/main.jsx']
      }
    },
    preview: {
      port: 8080
    },
    optimizeDeps: {
      // Injected by the preact-async-routes plugin: the dependency scanner cannot
      // discover it, and a dependency discovered after startup makes the dev server
      // reload every open page (breaks Cypress runs).
      include: ['@preact/async-loader/async.js'],
      rolldownOptions: {
        moduleTypes: {
          '.js': 'jsx'
        }
      }
    },
    build: {
      outDir: 'build',
      // preact-cli shipped a legacy nomodule bundle next to the modern one.
      // Vite only emits one bundle: lower its floor so older wall-mounted
      // tablets (Safari 13 / old Chromium webviews) keep working.
      target: ['es2019', 'chrome79', 'edge79', 'firefox72', 'safari13'],
      sourcemap: true,
      cssMinify: 'esbuild',
      rolldownOptions: {
        output: {
          codeSplitting: {
            groups: [
              {
                // Rolldown moves modules shared with lazy routes into their own chunk, whose CSS is
                // linked before index.css: keep the theme, the global styles and the dashboard
                // overrides together so the dashboard overrides still come after Tabler.
                name: 'app-styles',
                test: /(@gladysassistant\/theme-optimized\/|\/src\/style\/|\/src\/routes\/dashboard\/style\.css)/
              }
            ]
          },
          chunkFileNames: chunkInfo => {
            // Name route chunks after their route path (like preact-cli did),
            // e.g. src/routes/dashboard/index.js -> assets/route-dashboard.chunk.<hash>.js
            const facadeModuleId = (chunkInfo.facadeModuleId || '').split('?')[0];
            const routeChunkName = facadeModuleId ? getRouteChunkName(facadeModuleId, SRC_ROOT) : null;
            if (routeChunkName) {
              return `assets/${routeChunkName}.chunk.[hash].js`;
            }
            return 'assets/[name].chunk.[hash].js';
          }
        }
      }
    }
  };
});