wsj
3 days ago d26274d89d377067c1e2648192cffbf89464b361
vite.config.ts
@@ -2,6 +2,71 @@
import react from '@vitejs/plugin-react';
import { defineConfig, loadEnv } from 'vite';
/**
 * 布局、登录等入口页面会用到的 antd 组件。
 * 这些模块首屏必载,单独放进 antd chunk 以稳定缓存;
 * 表格、日期选择等只在业务页面使用的组件则交给 Rollup 按需分包。
 *
 * 注意:不要匹配 `antd/es/index.js`(`from 'antd'` 的 barrel 文件)。
 * manualChunks 会把 chunk 当成入口保留全部导出,barrel 进手动 chunk 后
 * 会把所有 antd 组件都拉进首屏(约 1.3MB),失去按需分包的意义。
 */
const ANTD_CORE_DIRS = [
  '_util',
  'app',
  'avatar',
  'breadcrumb',
  'button',
  'config-provider',
  'dropdown',
  'form',
  'input',
  'layout',
  'locale',
  'menu',
  'message',
  'modal',
  'notification',
  'space',
  'spin',
  'style',
  'tag',
  'theme',
  'tooltip',
  'version',
  'wave',
].join('|');
/** 第三方依赖拆包规则,页面本身通过路由懒加载按需加载。 */
const resolveVendorChunk = (id: string): string | undefined => {
  if (!id.includes('node_modules')) return undefined;
  const path = id.replace(/\\/g, '/');
  // 图标与 antd 互相引用,放在同一个 chunk,避免循环依赖。
  if (
    new RegExp(
      `\\/node_modules\\/(antd\\/es\\/(${ANTD_CORE_DIRS})\\/|@ant-design\\/(cssinjs|cssinjs-utils|colors|fast-color|icons|icons-svg)\\/)`,
    ).test(path)
  ) {
    return 'antd';
  }
  if (
    /\/node_modules\/(react|react-dom|scheduler|react-router|react-router-dom|@remix-run\/[^/]+)\//.test(
      path,
    )
  ) {
    return 'react';
  }
  if (/\/node_modules\/(axios|zustand|dayjs)\//.test(path)) {
    return 'vendor';
  }
  return undefined;
};
/** 开发环境通过 Vite 代理访问后端,避免浏览器跨域。 */
export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');
@@ -26,5 +91,14 @@
        },
      },
    },
    build: {
      // 首屏 chunk 已控制在 600KB 以内;按需加载的 ProComponents 业务包约 830KB。
      chunkSizeWarningLimit: 900,
      rollupOptions: {
        output: {
          manualChunks: resolveVendorChunk,
        },
      },
    },
  };
});