import { fileURLToPath } from 'node:url'; import { extname, relative, resolve } from 'path'; import react from '@vitejs/plugin-react'; import { glob } from 'glob'; import { visualizer } from 'rollup-plugin-visualizer'; import { defineConfig } from 'vite'; import dts from 'vite-plugin-dts'; import { libInjectCss } from 'vite-plugin-lib-inject-css'; import { version, name } from './package.json'; // https://vite.dev/config/ export default defineConfig(({ mode }) => { // check if it's development mode by --mode in package.json or script const isDevelopment = mode === 'development'; return { define: { __CHAT_UIKIT_VERSION__: JSON.stringify(version), __CHAT_UIKIT_NAME__: JSON.stringify(name), }, resolve: { alias: { '@': resolve(__dirname, 'src'), }, }, build: { lib: { entry: resolve(__dirname, 'src/index.ts'), formats: ['es'], }, rollupOptions: { external: (id) => { // external react and react-dom if (id === 'react' || id === 'react/jsx-runtime' || id.startsWith('react-dom')) { return true; } // external tuikit-atomicx-react and its sub-paths if (id === 'tuikit-atomicx-react' || id.startsWith('tuikit-atomicx-react/')) { return true; } // external other peer dependencies const externalPeers = [ '@tencentcloud/lite-chat', '@tencentcloud/tui-core-lite', '@tencentcloud/universal-api', '@tencentcloud/chat-uikit-engine-lite', '@tencentcloud/call-uikit-react', '@tencentcloud/uikit-base-component-react', 'zustand', '@mui/base', ]; return externalPeers.some(peer => id === peer || id.startsWith(`${peer}/`)); }, input: getInputEntries(), output: { format: 'es', compact: !isDevelopment, hoistTransitiveImports: false, entryFileNames: '[name].js', assetFileNames: 'styles/[name][extname]', manualChunks: { 'external_modules/classnames': [ 'classnames', ], 'external_modules/react-vendors': [ 'react-transition-group', ], }, }, treeshake: true, }, minify: isDevelopment ? false : 'esbuild', sourcemap: isDevelopment, }, plugins: [ react(), libInjectCss(), dts({ tsconfigPath: './tsconfig.app.json', include: ['src/**/*.ts', 'src/**/*.tsx'], exclude: ['**/*.stories.tsx', '**/*.stories.jsx'], outDir: 'dist', entryRoot: 'src', }), enableBuildStats(!isDevelopment), ], css: { modules: { generateScopedName: name => `uikit-${name}`, }, postcss: { plugins: [], }, preprocessorOptions: { scss: { api: 'modern-compiler', additionalData: ` @use "@tencentcloud/uikit-base-component-react/dist/styles/theme/util" as *; `, }, }, }, }; }); function getInputEntries() { const inputEntries = Object.fromEntries( glob.sync([ 'src/**/*.{ts,tsx}', ], { ignore: [ 'src/**/*.d.ts', 'src/**/*.stories.*', 'src/playground/**/*', ], }).map(file => [ // The name of the entry point // src/nested/foo.ts becomes nested/foo relative( 'src', file.slice(0, file.length - extname(file).length), ), // The absolute path to the entry file // lib/nested/foo.ts becomes User/../project/lib/nested/foo.ts fileURLToPath(new URL(file, import.meta.url)), ]), ); return inputEntries; } function enableBuildStats(enable: boolean = false) { return enable && visualizer({ filename: './.stats/stats.html', template: 'flamegraph', open: true, }); }