/// import type { PluginOption } from 'vite' import process from 'node:process' import { execSync } from 'node:child_process' import { join, resolve } from 'node:path' import VueI18n from '@intlify/unplugin-vue-i18n/vite' import templateCompilerOptions from '@tresjs/core/template-compiler-options' import Vue from '@vitejs/plugin-vue' import Unocss from 'unocss/vite' import Info from 'unplugin-info/vite' import Yaml from 'unplugin-yaml/vite' import mkcert from 'vite-plugin-mkcert' import VueDevTools from 'vite-plugin-vue-devtools' import Layouts from 'vite-plugin-vue-layouts' import VueMacros from 'vue-macros/vite' import VueRouter from 'vue-router/vite' import { tryCatch } from '@moeru/std' import { Download } from '@proj-airi/unplugin-fetch/vite' import { DownloadLive2DSDK } from '@proj-airi/unplugin-live2d-sdk/vite' import { defineConfig } from 'vite' // import { isEnvTruthy } from '@proj-airi/stage-shared' function isEnvTruthy(value: string | undefined | null): boolean { if (value == null) return false return /^(?:1|true|t|yes|y|on)$/i.test(value.trim()) } const stageUIAssetsRoot = resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-ui', 'src', 'assets')) const sharedCacheDir = resolve(join(import.meta.dirname, '..', '..', '.cache')) export default defineConfig({ optimizeDeps: { exclude: [ // Internal Packages '@proj-airi/stage-ui/*', '@proj-airi/drizzle-duckdb-wasm', '@proj-airi/drizzle-duckdb-wasm/*', // Static Assets: Models, Images, etc. 'public/assets/*', // Live2D SDK '@framework/live2dcubismframework', '@framework/math/cubismmatrix44', '@framework/type/csmvector', '@framework/math/cubismviewmatrix', '@framework/cubismdefaultparameterid', '@framework/cubismmodelsettingjson', '@framework/effect/cubismbreath', '@framework/effect/cubismeyeblink', '@framework/model/cubismusermodel', '@framework/motion/acubismmotion', '@framework/motion/cubismmotionqueuemanager', '@framework/type/csmmap', '@framework/utils/cubismdebug', '@framework/model/cubismmoc', ], }, resolve: { alias: { '@proj-airi/server-sdk': resolve(join(import.meta.dirname, '..', '..', 'packages', 'server-sdk', 'src')), '@proj-airi/i18n': resolve(join(import.meta.dirname, '..', '..', 'packages', 'i18n', 'src')), '@proj-airi/stage-ui': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-ui', 'src')), '@proj-airi/stage-layouts': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-layouts', 'src')), '@proj-airi/stage-pages': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-pages', 'src')), '@proj-airi/stage-shared': resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-shared', 'src')), }, }, server: { host: '0.0.0.0', port: 5273, fs: { // To mute errors like: // The request id ".../node_modules/@fontsource/sniglet/files/sniglet-latin-400-normal.woff" is outside of Vite serving allow list. // // See: https://vite.dev/config/server-options#server-fs-strict strict: false, }, warmup: { clientFiles: [ `${resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-ui', 'src'))}/*.vue`, `${resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-pages', 'src'))}/*.vue`, `${resolve(join(import.meta.dirname, '..', '..', 'packages', 'stage-layouts', 'src'))}/*.vue`, ], }, }, build: { sourcemap: true, }, worker: { format: 'es', rollupOptions: { output: { inlineDynamicImports: false, }, }, }, plugins: [ ...isEnvTruthy(process.env.VITE_SKIP_MKCERT ?? '') ? [] : [mkcert((() => { // Workaround: plugin's bundled downloader has a feaxios bug, prefer system mkcert const command = process.platform === 'win32' ? 'where' : 'which' const { data } = tryCatch(() => ({ mkcertPath: execSync(`${command} mkcert`, { stdio: 'pipe' }).toString().trim().split(/\r?\n/)[0] })) return data })())], Info(), Yaml(), VueMacros({ plugins: { vue: Vue({ include: [/\.vue$/, /\.md$/], ...templateCompilerOptions, }), vueJsx: false, }, betterDefine: false, }), VueRouter({ extensions: ['.vue', '.md'], dts: resolve(import.meta.dirname, 'src/typed-router.d.ts'), importMode: 'async', routesFolder: [ resolve(import.meta.dirname, 'src', 'pages'), { src: resolve(import.meta.dirname, '..', '..', 'packages', 'stage-pages', 'src', 'pages'), exclude: base => [ ...base, '**/settings/connection/index.vue', '**/settings/modules/beat-sync.vue', ], }, ], exclude: ['**/components/**'], }), // https://github.com/JohnCampionJr/vite-plugin-vue-layouts Layouts({ layoutsDirs: [ resolve(import.meta.dirname, 'src', 'layouts'), resolve(import.meta.dirname, '..', '..', 'packages', 'stage-layouts', 'src', 'layouts'), ], }), // https://github.com/antfu/unocss // see uno.config.ts for config Unocss(), // https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n VueI18n({ runtimeOnly: true, compositionOnly: true, fullInstall: true, }), // https://github.com/webfansplz/vite-plugin-vue-devtools VueDevTools(), DownloadLive2DSDK(), Download('https://dist.ayaka.moe/live2d-models/hiyori_free_zh.zip', 'hiyori_free_zh.zip', 'live2d/models', { parentDir: stageUIAssetsRoot, cacheDir: sharedCacheDir }), Download('https://dist.ayaka.moe/live2d-models/hiyori_pro_zh.zip', 'hiyori_pro_zh.zip', 'live2d/models', { parentDir: stageUIAssetsRoot, cacheDir: sharedCacheDir }), Download('https://dist.ayaka.moe/vrm-models/VRoid-Hub/AvatarSample-A/AvatarSample_A.vrm', 'AvatarSample_A.vrm', 'vrm/models/AvatarSample-A', { parentDir: stageUIAssetsRoot, cacheDir: sharedCacheDir }), Download('https://dist.ayaka.moe/vrm-models/VRoid-Hub/AvatarSample-B/AvatarSample_B.vrm', 'AvatarSample_B.vrm', 'vrm/models/AvatarSample-B', { parentDir: stageUIAssetsRoot, cacheDir: sharedCacheDir }), ...isEnvTruthy(process.env.VITE_CAP_SYNC_IOS_AFTER_BUILD ?? '') ? [{ name: 'proj-airi:capacitor-sync', closeBundle: { sequential: true, handler() { if (this.meta.watchMode) { execSync('cap sync ios', { stdio: 'inherit' }) } }, }, } as PluginOption] : [], { name: 'proj-airi:defines', config(ctx) { const define: Record = { 'import.meta.env.RUNTIME_ENVIRONMENT': '\'capacitor\'', } if (ctx.mode === 'development') { define['import.meta.env.URL_MODE'] = '\'server\'' } if (ctx.mode === 'production') { define['import.meta.env.URL_MODE'] = '\'file\'' } return { define } }, }, ], })