import { defineConfig } from 'vite' import type { Plugin } from 'vite' import vue from '@vitejs/plugin-vue' import { mkdirSync, readdirSync, writeFileSync } from 'node:fs' import { resolve } from 'node:path' function presetManifestPlugin(): Plugin { let presetDirectory = '' const locales = ['zh-CN', 'zh-TW', 'en', 'ja', 'ko', 'fr', 'de', 'pt-BR', 'es'] const updateManifest = () => { if (!presetDirectory) return mkdirSync(presetDirectory, { recursive: true }) const presets = readdirSync(presetDirectory) .filter((file) => file.toLowerCase().endsWith('.json') && file !== 'index.json') .sort((a, b) => a.localeCompare(b, 'zh-CN')) .map((file) => { const name = file.replace(/\.json$/i, '') return { file, name: Object.fromEntries(locales.map((locale) => [locale, name])), } }) writeFileSync(resolve(presetDirectory, 'index.json'), `${JSON.stringify(presets, null, 2)}\n`) } return { name: 'spine-particle-preset-manifest', configResolved(config) { presetDirectory = resolve(config.root, 'public/Preset') updateManifest() }, buildStart() { updateManifest() }, configureServer(server) { server.watcher.add(presetDirectory) const refresh = (file: string) => { if (file.startsWith(presetDirectory) && file.toLowerCase().endsWith('.json')) updateManifest() } server.watcher.on('add', refresh) server.watcher.on('unlink', refresh) }, } } export default defineConfig({ plugins: [vue(), presetManifestPlugin()], build: { sourcemap: false, rollupOptions: { output: { manualChunks(id) { if (id.includes('/node_modules/') || id.includes('/vendor/spine/')) return 'vendor' }, }, }, }, server: { port: 5173, host: true, }, resolve: { // 强制 spine-core 只解析到同一份模块,避免 spine-pixi-v7 与应用各自 import // 形成两份类实例,导致 `attachment instanceof RegionAttachment` 判 false、Spine 渲染空白。 dedupe: ['@esotericsoftware/spine-core', '@spine-particle/spine-core-4.3'], }, // 让 node_modules 里的 ESM 依赖能直接 work // 必须同时预打包 spine-core 与 spine-pixi-v7:否则 spine-core 会存在两份类实例, // 使 spine-pixi-v7 里 `attachment instanceof RegionAttachment` 对项目解析的 attachment 判 false, // 导致 renderMeshes 不生成任何网格、Spine 渲染空白。 optimizeDeps: { include: ['@esotericsoftware/spine-core', '@esotericsoftware/spine-pixi-v7'], exclude: ['@spine-particle/spine-core-4.3', '@spine-particle/spine-pixi-v7-4.3'], }, })