import { extname, relative, resolve } from 'path'; import { fileURLToPath } from 'node:url'; import { glob } from 'glob'; import { defineConfig } from 'vite'; import dts from 'vite-plugin-dts'; import vue from '@vitejs/plugin-vue'; import { libInjectCss } from 'vite-plugin-lib-inject-css'; import { peerDependencies } from './package.json'; export default defineConfig(({ command, mode }) => { const isPlayground = mode === 'playground'; if (isPlayground) { return { plugins: [vue()], root: resolve(__dirname), base: './', server: { port: 3000, open: true, }, build: { outDir: resolve(__dirname, 'dist-playground'), emptyOutDir: true, }, resolve: { alias: { '@': resolve(__dirname, 'src'), 'vue': 'vue/dist/vue.esm-bundler.js' } }, optimizeDeps: { exclude: ['vue-demi'], include: ['vue'] } }; } return { resolve: { alias: { '@': resolve(__dirname, '/src'), }, }, build: { emptyOutDir: true, cssMinify: false, minify: false, lib: { entry: resolve(__dirname, 'src/index.ts'), formats: ['es'], }, rollupOptions: { external: [ ...Object.keys(peerDependencies), ], input: getInputEntries(), output: { assetFileNames: 'styles/index[extname]', entryFileNames: '[name].js', }, }, }, plugins: [ vue(), dts({ include: ['src/**/*.ts', 'src/**/*.vue'], exclude: ['src/stories/**/*', 'src/**/*.stories.ts', 'src/**/*.stories.js', 'src/**/*.stories.vue'], }), { name: 'merge-css', enforce: 'post', apply: 'build', generateBundle(_, bundle) { let combinedCss = ''; for (const filename in bundle) { if (filename.endsWith('.css')) { const chunk = bundle[filename]; if (chunk.type === 'asset') { combinedCss += chunk.source; delete bundle[filename]; } } } this.emitFile({ type: 'asset', fileName: 'styles/index.css', source: combinedCss }); const entryChunk = bundle['index.js']; if (entryChunk?.type === 'chunk') { entryChunk.code = `import './styles/index.css';\n${entryChunk.code}`; } } }, ], css: { preprocessorOptions: { scss: { api: 'modern-compiler', }, }, }, }; }); function getInputEntries() { const inputEntries = Object.fromEntries( glob.sync('src/**/*.{ts,vue}', { ignore: [ 'src/stories/**/*', 'src/**/*.stories.{ts,js,vue}', 'src/**/*.story.{ts,js,vue}', 'src/**/*.test.{ts,js}', 'src/**/*.spec.{ts,js}', 'src/**/__tests__/**/*' ] }).map(file => [ relative( 'src', file.slice(0, file.length - extname(file).length), ), fileURLToPath(new URL(file, import.meta.url)), ]), ); return inputEntries; }