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 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) => ({ name: file.replace(/\.json$/i, ''), file })) 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()], 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'], }, })