mirror of
https://github.com/Moe-Sakura/frontend.git
synced 2026-03-19 05:39:45 +08:00
- Changed PWA registration type to 'autoUpdate' for immediate updates upon new version availability. - Removed obsolete busuanzi elements and replaced the data fetching method with a new API call for site statistics. - Simplified the UpdateToast component to trigger immediate updates without countdown, enhancing user experience.
225 lines
6.1 KiB
TypeScript
225 lines
6.1 KiB
TypeScript
import { defineConfig } from "vite";
|
||
import vue from "@vitejs/plugin-vue";
|
||
import tailwindcss from "@tailwindcss/vite";
|
||
import { fileURLToPath, URL } from 'node:url';
|
||
import { VitePWA } from 'vite-plugin-pwa';
|
||
|
||
export default defineConfig({
|
||
server: {
|
||
host: "localhost",
|
||
port: 5500,
|
||
// 预热常用文件
|
||
warmup: {
|
||
clientFiles: [
|
||
'./src/App.vue',
|
||
'./src/components/*.vue',
|
||
'./src/stores/*.ts',
|
||
],
|
||
},
|
||
},
|
||
|
||
plugins: [
|
||
vue({
|
||
script: {
|
||
// 响应式语法糖(如需要可启用)
|
||
defineModel: true,
|
||
},
|
||
}),
|
||
tailwindcss(),
|
||
// PWA 配置
|
||
VitePWA({
|
||
registerType: 'autoUpdate', // 收到新版本立即更新
|
||
includeAssets: ['logo.svg', 'robots.txt'],
|
||
manifest: {
|
||
name: 'SearchGal - Galgame 聚合搜索',
|
||
short_name: 'SearchGal',
|
||
description: '多平台 Galgame 资源聚合搜索引擎',
|
||
start_url: '/',
|
||
display: 'standalone',
|
||
background_color: '#fff5fa',
|
||
theme_color: '#ff1493',
|
||
orientation: 'portrait-primary',
|
||
scope: '/',
|
||
lang: 'zh-CN',
|
||
dir: 'ltr',
|
||
icons: [
|
||
{
|
||
src: '/logo.svg',
|
||
sizes: 'any',
|
||
type: 'image/svg+xml',
|
||
purpose: 'any maskable',
|
||
},
|
||
],
|
||
categories: ['entertainment', 'games', 'utilities'],
|
||
shortcuts: [
|
||
{
|
||
name: '游戏模式搜索',
|
||
short_name: '游戏搜索',
|
||
description: '快速搜索游戏资源',
|
||
url: '/?mode=game',
|
||
icons: [{ src: '/logo.svg', sizes: 'any' }],
|
||
},
|
||
{
|
||
name: '补丁模式搜索',
|
||
short_name: '补丁搜索',
|
||
description: '搜索游戏补丁资源',
|
||
url: '/?mode=patch',
|
||
icons: [{ src: '/logo.svg', sizes: 'any' }],
|
||
},
|
||
],
|
||
},
|
||
workbox: {
|
||
// 预缓存所有构建产物
|
||
globPatterns: ['**/*.{js,css,html,svg,png,ico,woff2}'],
|
||
// 运行时缓存策略
|
||
runtimeCaching: [
|
||
{
|
||
// 字体文件 - 缓存优先
|
||
urlPattern: /^https:\/\/fonts\.(googleapis|gstatic)\.com\/.*/i,
|
||
handler: 'CacheFirst',
|
||
options: {
|
||
cacheName: 'google-fonts',
|
||
expiration: {
|
||
maxEntries: 10,
|
||
maxAgeSeconds: 60 * 60 * 24 * 365, // 1 年
|
||
},
|
||
},
|
||
},
|
||
{
|
||
// 图片 API - 网络优先
|
||
urlPattern: /^https:\/\/api\.illlights\.com\/.*/i,
|
||
handler: 'NetworkFirst',
|
||
options: {
|
||
cacheName: 'background-images',
|
||
expiration: {
|
||
maxEntries: 20,
|
||
maxAgeSeconds: 60 * 60 * 24, // 1 天
|
||
},
|
||
},
|
||
},
|
||
{
|
||
// VNDB API - 网络优先
|
||
urlPattern: /^https:\/\/api\.vndb\.org\/.*/i,
|
||
handler: 'NetworkFirst',
|
||
options: {
|
||
cacheName: 'vndb-api',
|
||
expiration: {
|
||
maxEntries: 50,
|
||
maxAgeSeconds: 60 * 30, // 30 分钟
|
||
},
|
||
},
|
||
},
|
||
],
|
||
// 离线时的导航回退
|
||
navigateFallback: null, // 不使用默认回退,由 offlineFallback 处理
|
||
},
|
||
// 开发环境启用 SW(便于测试)
|
||
devOptions: {
|
||
enabled: false, // 开发时禁用,避免干扰
|
||
},
|
||
}),
|
||
],
|
||
|
||
resolve: {
|
||
alias: {
|
||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||
}
|
||
},
|
||
|
||
// 构建优化
|
||
build: {
|
||
// 使用现代浏览器目标
|
||
target: 'esnext',
|
||
// 启用 CSS 代码分割
|
||
cssCodeSplit: true,
|
||
// 压缩选项
|
||
minify: 'esbuild',
|
||
// 源码映射(生产环境关闭)
|
||
sourcemap: false,
|
||
// Chunk 大小警告阈值 (KB)
|
||
chunkSizeWarningLimit: 600,
|
||
// Rollup 配置
|
||
rollupOptions: {
|
||
output: {
|
||
// 资源文件名
|
||
assetFileNames: (assetInfo) => {
|
||
const name = assetInfo.name || '';
|
||
// 字体文件
|
||
if (/\.(woff2?|eot|ttf|otf)$/i.test(name)) {
|
||
return 'fonts/[name]-[hash][extname]';
|
||
}
|
||
// 图片文件
|
||
if (/\.(png|jpe?g|gif|svg|webp|ico)$/i.test(name)) {
|
||
return 'images/[name]-[hash][extname]';
|
||
}
|
||
// CSS 文件
|
||
if (/\.css$/i.test(name)) {
|
||
return 'css/[name]-[hash][extname]';
|
||
}
|
||
return 'assets/[name]-[hash][extname]';
|
||
},
|
||
// JS 入口文件名
|
||
entryFileNames: 'js/[name]-[hash].js',
|
||
// JS Chunk 文件名
|
||
chunkFileNames: 'js/[name]-[hash].js',
|
||
// 手动分包
|
||
manualChunks: (id) => {
|
||
if (id.includes('node_modules')) {
|
||
// Vue 核心
|
||
if (id.includes('/vue/') || id.includes('/@vue/')) {
|
||
return 'vue-core';
|
||
}
|
||
// Pinia 状态管理
|
||
if (id.includes('/pinia/')) {
|
||
return 'pinia';
|
||
}
|
||
// UI 库
|
||
if (id.includes('/lucide-vue-next/')) {
|
||
return 'ui-libs';
|
||
}
|
||
// Artalk 评论
|
||
if (id.includes('/artalk/')) {
|
||
return 'artalk';
|
||
}
|
||
// 代码编辑器
|
||
if (id.includes('/prismjs/') || id.includes('/vue-prism-editor/')) {
|
||
return 'editor';
|
||
}
|
||
// Fancybox
|
||
if (id.includes('/@fancyapps/')) {
|
||
return 'fancybox';
|
||
}
|
||
// 其他第三方库
|
||
return 'vendor';
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
|
||
// 依赖优化
|
||
optimizeDeps: {
|
||
// 预构建的依赖
|
||
include: [
|
||
'vue',
|
||
'pinia',
|
||
'lucide-vue-next',
|
||
],
|
||
// 排除不需要预构建的
|
||
exclude: ['artalk'],
|
||
},
|
||
|
||
// esbuild 配置
|
||
esbuild: {
|
||
// 生产环境移除 console 和 debugger
|
||
drop: process.env.NODE_ENV === 'production' ? ['console', 'debugger'] : [],
|
||
// 压缩选项
|
||
legalComments: 'none',
|
||
},
|
||
|
||
// CSS 配置
|
||
css: {
|
||
devSourcemap: true,
|
||
},
|
||
});
|