Ctrl K
ComunidadGuías…

vite.config.js

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

Archivo original ↗Preguntar a KiBot
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import { readFileSync } from "node:fs";
import { execSync } from "node:child_process";
import { ViteImageOptimizer } from "vite-plugin-image-optimizer";
import { VitePWA } from "vite-plugin-pwa";
import { sri } from "vite-plugin-sri3";
import { compression } from "vite-plugin-compression2";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJson = JSON.parse(
  readFileSync(new URL("./package.json", import.meta.url), "utf-8"),
);

function resolveAppVersion() {
  const packageVersion = packageJson.version;

  if (packageVersion && packageVersion !== "0.0.0") {
    return packageVersion;
  }

  try {
    return execSync("git describe --tags --always --dirty", {
      encoding: "utf-8",
    }).trim();
  } catch {
    return packageVersion || "unknown";
  }
}

const appVersion = resolveAppVersion();

export default defineConfig(({ command, mode }) => {
  const isProductionBuild = command === "build" && mode === "production";

  return {
    plugins: [
      react(),
      VitePWA({
        registerType: "autoUpdate",
        injectRegister: "auto",
        includeAssets: [
          "favicon.svg",
          "apple-touch-icon.png",
          "maskable-icon.svg",
          "safari-pinned-tab.svg",
        ],
        manifest: {
          name: "Tuning Visualizer",
          short_name: "TuningViz",
          start_url: "/",
          scope: "/",
          display: "standalone",
          background_color: "#101214",
          theme_color: "#ff6a00",
          icons: [
            {
              src: "/maskable-icon-192.png",
              sizes: "192x192",
              type: "image/png",
              purpose: "any maskable",
            },
            {
              src: "/maskable-icon-512.png",
              sizes: "512x512",
              type: "image/png",
              purpose: "any maskable",
            },
          ],
        },
        workbox: {
          globPatterns: ["**/*.{js,css,html,svg,png,webmanifest}"],
          cleanupOutdatedCaches: true,
          navigateFallback: "/index.html",
        },
        devOptions: {
          enabled: false,
        },
      }),
      ...(isProductionBuild
        ? [
            ViteImageOptimizer({
              png: { quality: 80 },
              jpeg: { quality: 80 },
              jpg: { quality: 80 },
              webp: { quality: 80 },
              avif: { quality: 50 },
            }),
            sri(),
            compression({
              algorithms: ["gzip", "brotliCompress"],
              exclude: [/\.(png|jpe?g|webp|avif|gif|woff2?)$/i],
              deleteOriginalAssets: false,
            }),
          ]
        : []),
    ],

    define: {
      "import.meta.env.VITE_APP_VERSION": JSON.stringify(appVersion),
    },

    css: {
      transformer: "lightningcss",
      lightningcss: {
        targets: { chrome: 109, safari: 15, firefox: 102, edge: 109 },
        drafts: { nesting: true, customMedia: true },
      },
    },

    build: {
      target: ["chrome109", "safari15", "firefox102", "edge109"],
      minify: isProductionBuild ? "oxc" : false,
      cssMinify: "lightningcss",
      rolldownOptions: {
        output: {
          ...(isProductionBuild
            ? { minify: { compress: { dropConsole: true }, mangle: true } }
            : {}),
          manualChunks(id) {
            if (id.includes("/@dmnerd/microtonal/")) {
              return "theory";
            }

            if (!id.includes("node_modules")) {
              return;
            }

            if (id.includes("/react/") || id.includes("/react-dom/")) {
              return "react-core";
            }

            if (
              id.includes("/react-icons/") ||
              id.includes("/react-hot-toast/") ||
              id.includes("/clsx/")
            ) {
              return "ui-kit";
            }

            if (id.includes("/fuse.js/")) {
              return "search";
            }

            if (id.includes("/json-edit-react/")) {
              return "editor";
            }

            if (id.includes("/react-qr-code/") || id.includes("/qr.js/")) {
              return "share";
            }

            if (id.includes("/zustand/")) {
              return "state";
            }

            return "vendor";
          },
        },
      },
    },

    resolve: {
      alias: [
        { find: "@app", replacement: resolve(__dirname, "src/app") },
        { find: "@features", replacement: resolve(__dirname, "src/features") },
        { find: "@shared", replacement: resolve(__dirname, "src/shared") },
        { find: "@domain", replacement: resolve(__dirname, "src/domain") },
        { find: "@styles", replacement: resolve(__dirname, "src/styles") },
        { find: "@", replacement: resolve(__dirname, "src") },
      ],
    },
  };
});