import { readFileSync } from 'node:fs' import { fileURLToPath } from 'node:url' import vue from '@vitejs/plugin-vue' import { defineConfig } from 'vite' import dts from 'vite-plugin-dts' // 命名空间单一事实源在 @g3soft/tokens 的 SCSS 里(SCSS 无法读 JS,故 JS 向 SCSS 取)。 // 这里烘焙成 JS 常量 __G3_NAMESPACE__:运行时 useNamespace() 的默认值 + dev 一致性校验都用它。 // 消费方若用自定义 $namespace 重编译,需在自身构建里同步 define 同名常量(见 README)。 const configScssPath = fileURLToPath( new URL('../tokens/src/scss/_config.scss', import.meta.url), ) const configScss = readFileSync(configScssPath, 'utf-8') function readScssDefault(name: string, fallback: string): string { const match = configScss.match( new RegExp(`\\$${name}\\s*:\\s*['"]([^'"]+)['"]\\s*!default`), ) return match ? match[1] : fallback } const NAMESPACE = readScssDefault('namespace', 'g3') const STATE_PREFIX = readScssDefault('state-prefix', 'is') /** * 组件库构建:产出 ESM + 类型声明。 * * 关键点: * - vue 必须外置(external),否则包里会打进一份 Vue,消费方出现双实例 * - preserveModules 保留源码结构,消费方能按需 tree-shaking * - vite-plugin-dts 生成 dist/index.d.ts,配合 package.json 的 exports.types * - define.__G3_NAMESPACE__ 把编译期命名空间烘焙进 JS,供运行时 useNamespace 使用 */ export default defineConfig({ plugins: [ vue(), dts({ // 只产出声明文件,JS 交给 vite 本体 include: ['src'], outDir: 'dist', rollupTypes: true, }), ], define: { __G3_NAMESPACE__: JSON.stringify(NAMESPACE), __G3_STATE_PREFIX__: JSON.stringify(STATE_PREFIX), }, css: { preprocessorOptions: { // 组件 SCSS 一律走 modern compiler API;库自身只用默认 $namespace,不加 additionalData。 scss: { api: 'modern-compiler', }, }, }, build: { lib: { entry: fileURLToPath(new URL('./src/index.ts', import.meta.url)), formats: ['es'], fileName: () => 'index.js', }, rollupOptions: { // 图标库同理外置:由消费方(或本包的 dependencies)解析,避免重复打包 external: ['vue', '@lucide/vue'], output: { preserveModules: true, preserveModulesRoot: 'src', entryFileNames: '[name].js', assetFileNames: 'style.css', }, }, }, })