Ctrl K
ComunidadGuías…

interface/rsbuild.config.ts

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

Archivo original ↗Preguntar a KiBot
import { pluginPWA } from './pluginPWA';

import path from 'node:path';
import { defineConfig } from '@rsbuild/core';
import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginSass } from '@rsbuild/plugin-sass';

const envName = process.env.NODE_ENV ?? 'development';
console.log(`Building for environment: ${envName}`);
const isDevelopment = envName !== 'production';
const interfaceSource = path.resolve(__dirname, 'src');

// If we are using development lite, then this changes the behavior of the config significantly. We instead proxy the
// staging or production API here to allow for frontend development only against real data. Requires a staging or
// production account.
const developmentLite = Boolean(process.env.MONETR_DEVELOPMENT_LITE ?? false);
const developmentLiteTarget = process.env.MONETR_DEVELOPMENT_LITE_TARGET ?? 'my.monetr.dev';
if (developmentLite) {
  console.log(`development lite environment will be used, upstream: ${developmentLiteTarget}`);
}

const version = `v${process.env.RELEASE_VERSION ?? ''}`;

// HMR replacement gets **fucked** if we are using content hash. So use name when we are
// in development mode.
const filename = isDevelopment ? '[name]' : '[contenthash:8]';

export default defineConfig({
  mode: isDevelopment ? 'development' : 'production',
  source: {
    define: {
      CONFIG: JSON.stringify({}),
      REVISION: JSON.stringify(process.env.RELEASE_REVISION),
      RELEASE: JSON.stringify(version),
      NODE_VERSION: process.version,
    },
  },
  resolve: {
    alias: {
      '@monetr/interface': interfaceSource,
    },
  },
  dev: {
    hmr: isDevelopment,
    liveReload: isDevelopment,
  },
  server: {
    publicDir: {
      name: path.resolve(__dirname, 'public'),
      copyOnBuild: false,
    },
    port: 3000,
    historyApiFallback: true,
    host: developmentLite ? 'localhost' : '0.0.0.0',
    proxy: developmentLite
      ? {
          '/api': {
            // When we are in development-lite mode, proxy API calls to the upstream API server that they have specified.
            target: `https://${developmentLiteTarget}`,
            changeOrigin: true,
            cookieDomainRewrite: 'localhost',
            ws: true, // For file uploads
          },
        }
      : undefined,
  },
  html: {
    template: path.resolve(__dirname, 'public/index.html'),
    templateParameters: {
      // When we are doing local dev then don't use anything, maybe use an env var in the future but thats it. But
      // for a production build add the go template string in so that the server can provide the DSN.
      SENTRY_DSN: isDevelopment ? `${process.env.MONETR_SENTRY_DSN ?? ''}` : '{{ .SentryDSN }}',
      // The preconnect tag is built entirely on the server so that we can skip it for localhost or unset external
      // URLs. In dev there is nothing to preconnect to, so collapse the placeholder to an empty string.
      PRECONNECT_TAG: isDevelopment ? '' : '{{ .PreconnectTag }}',
    },
    // Dont use the favicon here, favicon is handled by the PWA plugin.
    mountId: 'root',
  },
  performance: {
    // Split vendor code into groups that change independently, so a dependency bump only busts the cache for its own
    // group instead of one large vendor chunk.
    chunkSplit: {
      strategy: 'split-by-experience',
      forceSplitting: {
        'lib-sentry': /node_modules[\\/]@sentry/,
        // Exclude date-fns locales, those are lazy loaded by useLocale and would otherwise be pulled into this chunk.
        'lib-date': /node_modules[\\/](date-fns(?![\\/]locale)|@date-fns|react-day-picker|rrule)/,
        'lib-query': /node_modules[\\/]@tanstack/,
        'lib-forms': /node_modules[\\/](formik|lodash-es|downshift|react-number-format)/,
        'lib-ui': /node_modules[\\/](@radix-ui|@monetr[\\/]vaul|lucide-react|cmdk)/,
      },
    },
    preload: {
      type: 'all-assets',
      include: [/inter-latin-wght-normal.*\.woff2$/, /jetbrains-mono-latin-\d+-normal.*\.woff2$/],
    },
  },
  output: {
    target: 'web',
    distPath: {
      root: path.resolve(__dirname, '../server/ui/static'),
      js: 'assets/scripts',
      css: 'assets/styles',
      image: 'assets/images',
      font: 'assets/fonts',
    },
    filename: isDevelopment
      ? undefined
      : {
          js: `${filename}.js`,
          css: `${filename}.css`,
          image: `[name].${filename}[ext]`,
          font: `[name].${filename}[ext]`,
        },
    cleanDistPath: false, // Handled by cmake
    // Small font subsets were getting base64'd into the main CSS, keep them as files so they only load when needed.
    dataUriLimit: {
      font: 0,
    },
    charset: 'utf8',
    filenameHash: true,
    manifest: false,
    minify: {
      js: true,
      css: true,
    },
    sourceMap: {
      js: isDevelopment ? 'inline-source-map' : 'source-map',
      css: true,
    },
    cssModules: isDevelopment
      ? undefined
      : {
          // Hash the class names when we are in a production build.
          localIdentName: '[hash:base64:6]',
        },
    copy: [
      {
        from: 'public/manifest.json',
        to: 'manifest.json',
      },
      {
        from: 'public/robots.txt',
        to: 'robots.txt',
      },
    ],
  },
  security: {
    sri: {
      enable: !isDevelopment,
      algorithm: 'sha512',
    },
  },
  plugins: [
    pluginReact(),
    pluginSass(),
    pluginBabel({
      include: /\.(?:jsx|tsx)$/,
      babelLoaderOptions(opts) {
        opts.plugins?.unshift(['babel-plugin-react-compiler', { target: '19' }]);
      },
    }),
    pluginPWA({
      logo: path.resolve(__dirname, '../images/logo.png'),
      background: '#19161f',
      quality: 90,
    }),
  ],
});