mirror of
https://github.com/Moe-Sakura/frontend.git
synced 2026-03-18 05:33:18 +08:00
34
public/data/friends.json
Normal file
34
public/data/friends.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"friends": [
|
||||
{
|
||||
"name": "Jurangren",
|
||||
"desc": "本站后端大手子!",
|
||||
"url": "https://github.com/Jurangren",
|
||||
"logo": "https://avatars.githubusercontent.com/u/111159360"
|
||||
},
|
||||
{
|
||||
"name": "Asuna",
|
||||
"desc": "LINK START!",
|
||||
"url": "https://saop.cc/",
|
||||
"logo": "https://saop.cc/avatar.webp"
|
||||
},
|
||||
{
|
||||
"name": "VNDB",
|
||||
"desc": "Visual Novel Database",
|
||||
"url": "https://vndb.org/",
|
||||
"logo": "https://vndb.org/favicon.ico"
|
||||
},
|
||||
{
|
||||
"name": "梓澪",
|
||||
"desc": "梓澪の妙妙屋",
|
||||
"url": "https://zi0.cc/",
|
||||
"logo": "https://img.mjj.today/2023/01/23/2b6331a29bf32d2af96a2537e10a5ee8.webp"
|
||||
},
|
||||
{
|
||||
"name": "VNS",
|
||||
"desc": "Visual Novel",
|
||||
"url": "https://gal.saop.cc",
|
||||
"logo": "https://gal.saop.cc/images/logo.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,43 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
|
||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd
|
||||
http://www.google.com/schemas/sitemap-image/1.1
|
||||
http://www.google.com/schemas/sitemap-image/1.1/sitemap-image.xsd">
|
||||
|
||||
<!-- 主页 -->
|
||||
<url>
|
||||
<loc>https://searchgal.homes/</loc>
|
||||
<lastmod>2025-12-21</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>1.0</priority>
|
||||
<image:image>
|
||||
<image:loc>https://searchgal.homes/logo.svg</image:loc>
|
||||
<image:title>SearchGal - Galgame 聚合搜索</image:title>
|
||||
<image:caption>Galgame 资源聚合搜索引擎,支持多站点搜索</image:caption>
|
||||
</image:image>
|
||||
<image:image>
|
||||
<image:loc>https://searchgal.homes/og-image.png</image:loc>
|
||||
<image:title>SearchGal 社交分享图</image:title>
|
||||
</image:image>
|
||||
</url>
|
||||
|
||||
<!-- AI/LLM 信息页 -->
|
||||
<url>
|
||||
<loc>https://searchgal.homes/llms.txt</loc>
|
||||
<lastmod>2025-12-21</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<url>
|
||||
<loc>https://searchgal.homes/manifest.json</loc>
|
||||
<lastmod>2025-12-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.3</priority>
|
||||
</url>
|
||||
|
||||
</urlset>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
|
||||
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
|
||||
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd
|
||||
http://www.google.com/schemas/sitemap-image/1.1
|
||||
http://www.google.com/schemas/sitemap-image/1.1/sitemap-image.xsd">
|
||||
|
||||
<!-- 主页 -->
|
||||
<url>
|
||||
<loc>https://searchgal.homes/</loc>
|
||||
<lastmod>2025-12-21</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
<priority>1.0</priority>
|
||||
<image:image>
|
||||
<image:loc>https://searchgal.homes/logo.svg</image:loc>
|
||||
<image:title>SearchGal - Galgame 聚合搜索</image:title>
|
||||
<image:caption>Galgame 资源聚合搜索引擎,支持多站点搜索</image:caption>
|
||||
</image:image>
|
||||
<image:image>
|
||||
<image:loc>https://searchgal.homes/og-image.png</image:loc>
|
||||
<image:title>SearchGal 社交分享图</image:title>
|
||||
</image:image>
|
||||
</url>
|
||||
|
||||
<!-- AI/LLM 信息页 -->
|
||||
<url>
|
||||
<loc>https://searchgal.homes/llms.txt</loc>
|
||||
<lastmod>2025-12-21</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.6</priority>
|
||||
</url>
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<url>
|
||||
<loc>https://searchgal.homes/manifest.json</loc>
|
||||
<lastmod>2025-12-21</lastmod>
|
||||
<changefreq>monthly</changefreq>
|
||||
<priority>0.3</priority>
|
||||
</url>
|
||||
|
||||
</urlset>
|
||||
|
||||
@@ -390,6 +390,72 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 友情链接 -->
|
||||
<div
|
||||
v-if="friendLinks.length > 0"
|
||||
class="w-full max-w-5xl mx-auto mt-6 sm:mt-8 px-2 sm:px-0 animate-fade-in animation-delay-1000"
|
||||
>
|
||||
<div
|
||||
class="glassmorphism-card rounded-2xl sm:rounded-3xl
|
||||
shadow-xl shadow-theme-primary/10 dark:shadow-theme-accent/20
|
||||
p-4 sm:p-6"
|
||||
>
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2
|
||||
class="text-lg sm:text-xl font-bold
|
||||
text-theme-primary dark:text-theme-accent
|
||||
flex items-center gap-2"
|
||||
>
|
||||
<Link2 :size="18" />
|
||||
友情链接
|
||||
</h2>
|
||||
<a
|
||||
href="https://github.com/Moe-Sakura/frontend/edit/dev/public/data/friends.json"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium
|
||||
text-white bg-gradient-to-r from-[#ff1493] to-[#d946ef]
|
||||
shadow-md shadow-pink-500/20 hover:shadow-lg hover:shadow-pink-500/30
|
||||
transition-all"
|
||||
>
|
||||
<GitPullRequestArrow :size="14" />
|
||||
<span>交换友链</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4">
|
||||
<a
|
||||
v-for="friend in friendLinks"
|
||||
:key="friend.url"
|
||||
:href="friend.url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="friend-card group flex items-center gap-3 p-3 rounded-xl
|
||||
bg-white/50 dark:bg-slate-800/50
|
||||
border border-gray-200/50 dark:border-slate-700/50
|
||||
hover:border-[#ff1493]/30 dark:hover:border-[#ff69b4]/30
|
||||
hover:shadow-lg hover:shadow-pink-500/10
|
||||
transition-all duration-300"
|
||||
>
|
||||
<img
|
||||
:src="friend.logo"
|
||||
:alt="friend.name"
|
||||
class="w-10 h-10 rounded-lg object-cover bg-gray-100 dark:bg-slate-700 flex-shrink-0"
|
||||
loading="lazy"
|
||||
@error="handleFriendLogoError"
|
||||
/>
|
||||
<div class="flex-1 min-w-0">
|
||||
<h3 class="font-bold text-gray-800 dark:text-white text-sm group-hover:text-[#ff1493] dark:group-hover:text-[#ff69b4] transition-colors truncate">
|
||||
{{ friend.name }}
|
||||
</h3>
|
||||
<p class="text-xs text-gray-500 dark:text-slate-400 truncate">
|
||||
{{ friend.desc }}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -418,6 +484,8 @@ import {
|
||||
Loader2,
|
||||
CornerDownLeft,
|
||||
XCircle,
|
||||
Link2,
|
||||
GitPullRequestArrow,
|
||||
} from 'lucide-vue-next'
|
||||
import { getSearchParamsFromURL, updateURLParams, onURLParamsChange } from '@/utils/urlParams'
|
||||
import { saveSearchHistory } from '@/utils/persistence'
|
||||
@@ -428,6 +496,32 @@ const customApi = ref('')
|
||||
const searchMode = ref<'game' | 'patch'>('game')
|
||||
let cleanupURLListener: (() => void) | null = null
|
||||
|
||||
// 友情链接
|
||||
interface FriendLink {
|
||||
name: string
|
||||
desc: string
|
||||
url: string
|
||||
logo: string
|
||||
}
|
||||
const friendLinks = ref<FriendLink[]>([])
|
||||
|
||||
// 获取友情链接数据
|
||||
async function loadFriendLinks() {
|
||||
try {
|
||||
const res = await fetch('/data/friends.json')
|
||||
const data = await res.json()
|
||||
friendLinks.value = data.friends || []
|
||||
} catch {
|
||||
// 静默失败
|
||||
}
|
||||
}
|
||||
|
||||
// 友链 logo 加载失败时的处理
|
||||
function handleFriendLogoError(e: Event) {
|
||||
const img = e.target as HTMLImageElement
|
||||
img.src = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23ff1493"><circle cx="12" cy="12" r="10"/></svg>'
|
||||
}
|
||||
|
||||
// 搜索防抖 - 防止 800ms 内重复触发
|
||||
const { isLocked: isSearchLocked, click: debouncedSearchTrigger } = useDebouncedClick(800)
|
||||
|
||||
@@ -472,6 +566,9 @@ onMounted(() => {
|
||||
isUpdatingFromURL = false
|
||||
}, 200)
|
||||
})
|
||||
|
||||
// 加载友情链接
|
||||
loadFriendLinks()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
@@ -23,39 +23,23 @@
|
||||
{{ countdown > 0 ? `${countdown} 秒后自动更新...` : '正在更新...' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 立即更新按钮 -->
|
||||
<button
|
||||
v-if="countdown > 0"
|
||||
class="flex-shrink-0 px-3 py-1.5 rounded-xl bg-white/20 hover:bg-white/30 text-xs font-medium transition-colors"
|
||||
@click="updateNow"
|
||||
>
|
||||
立即更新
|
||||
</button>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import { ref, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { RefreshCw } from 'lucide-vue-next'
|
||||
import { playNotification, playTap, playSwipe } from '@/composables/useSound'
|
||||
import { playNotification } from '@/composables/useSound'
|
||||
|
||||
const props = defineProps<{
|
||||
isVisible: boolean
|
||||
onUpdate: () => void
|
||||
}>()
|
||||
|
||||
const countdown = ref(3)
|
||||
const countdown = ref(5)
|
||||
let timer: number | null = null
|
||||
|
||||
function updateNow() {
|
||||
playTap()
|
||||
countdown.value = 0
|
||||
playSwipe()
|
||||
props.onUpdate()
|
||||
}
|
||||
|
||||
function startCountdown() {
|
||||
// 先清除可能存在的旧定时器,避免创建多个并发定时器
|
||||
if (timer) {
|
||||
@@ -64,7 +48,7 @@ function startCountdown() {
|
||||
}
|
||||
|
||||
playNotification()
|
||||
countdown.value = 3
|
||||
countdown.value = 5
|
||||
timer = window.setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) {
|
||||
@@ -90,7 +74,6 @@ onUnmounted(() => {
|
||||
})
|
||||
|
||||
// 监听 isVisible 变化
|
||||
import { watch } from 'vue'
|
||||
watch(() => props.isVisible, (visible) => {
|
||||
if (visible) {
|
||||
startCountdown()
|
||||
|
||||
@@ -43,7 +43,7 @@ async function getSnd(): Promise<Snd | null> {
|
||||
try {
|
||||
isLoading = true
|
||||
sndInstance = new Snd()
|
||||
|
||||
|
||||
// 加载音效套件
|
||||
const kit = currentKit.value === 'SND01' ? Snd.KITS.SND01 : Snd.KITS.SND02
|
||||
await sndInstance.load(kit)
|
||||
|
||||
@@ -221,7 +221,7 @@ export const useUIStore = defineStore('ui', () => {
|
||||
// 解析失败,使用默认值
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 从 sessionStorage 加载会话状态(刷新恢复)
|
||||
function loadSessionState() {
|
||||
try {
|
||||
@@ -259,7 +259,7 @@ export const useUIStore = defineStore('ui', () => {
|
||||
// 保存失败,静默处理
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 保存会话状态到 sessionStorage(刷新恢复)
|
||||
function saveSessionState() {
|
||||
try {
|
||||
|
||||
292
vite.config.ts
292
vite.config.ts
@@ -1,146 +1,146 @@
|
||||
import { defineConfig } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import { fileURLToPath, URL } from 'node:url';
|
||||
import { swVersionPlugin } from './scripts/sw-version-plugin';
|
||||
|
||||
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(),
|
||||
// 构建时自动注入 SW 版本号
|
||||
swVersionPlugin({
|
||||
swPath: 'sw.js',
|
||||
includeGitHash: true,
|
||||
}),
|
||||
],
|
||||
|
||||
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';
|
||||
}
|
||||
// 动画库
|
||||
if (id.includes('/animejs/')) {
|
||||
return 'anime';
|
||||
}
|
||||
// Artalk 评论
|
||||
if (id.includes('/artalk/')) {
|
||||
return 'artalk';
|
||||
}
|
||||
// 代码编辑器
|
||||
if (id.includes('/prismjs/') || id.includes('/vue-prism-editor/')) {
|
||||
return 'editor';
|
||||
}
|
||||
// 音效库
|
||||
if (id.includes('/snd-lib/')) {
|
||||
return 'sound';
|
||||
}
|
||||
// Fancybox
|
||||
if (id.includes('/@fancyapps/')) {
|
||||
return 'fancybox';
|
||||
}
|
||||
// 其他第三方库
|
||||
return 'vendor';
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// 依赖优化
|
||||
optimizeDeps: {
|
||||
// 预构建的依赖
|
||||
include: [
|
||||
'vue',
|
||||
'pinia',
|
||||
'lucide-vue-next',
|
||||
'animejs',
|
||||
],
|
||||
// 排除不需要预构建的
|
||||
exclude: ['artalk'],
|
||||
},
|
||||
|
||||
// esbuild 配置
|
||||
esbuild: {
|
||||
// 生产环境移除 console 和 debugger
|
||||
drop: process.env.NODE_ENV === 'production' ? ['console', 'debugger'] : [],
|
||||
// 压缩选项
|
||||
legalComments: 'none',
|
||||
},
|
||||
|
||||
// CSS 配置
|
||||
css: {
|
||||
devSourcemap: true,
|
||||
},
|
||||
});
|
||||
import { defineConfig } from "vite";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import { fileURLToPath, URL } from 'node:url';
|
||||
import { swVersionPlugin } from './scripts/sw-version-plugin';
|
||||
|
||||
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(),
|
||||
// 构建时自动注入 SW 版本号
|
||||
swVersionPlugin({
|
||||
swPath: 'sw.js',
|
||||
includeGitHash: true,
|
||||
}),
|
||||
],
|
||||
|
||||
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';
|
||||
}
|
||||
// 动画库
|
||||
if (id.includes('/animejs/')) {
|
||||
return 'anime';
|
||||
}
|
||||
// Artalk 评论
|
||||
if (id.includes('/artalk/')) {
|
||||
return 'artalk';
|
||||
}
|
||||
// 代码编辑器
|
||||
if (id.includes('/prismjs/') || id.includes('/vue-prism-editor/')) {
|
||||
return 'editor';
|
||||
}
|
||||
// 音效库
|
||||
if (id.includes('/snd-lib/')) {
|
||||
return 'sound';
|
||||
}
|
||||
// Fancybox
|
||||
if (id.includes('/@fancyapps/')) {
|
||||
return 'fancybox';
|
||||
}
|
||||
// 其他第三方库
|
||||
return 'vendor';
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// 依赖优化
|
||||
optimizeDeps: {
|
||||
// 预构建的依赖
|
||||
include: [
|
||||
'vue',
|
||||
'pinia',
|
||||
'lucide-vue-next',
|
||||
'animejs',
|
||||
],
|
||||
// 排除不需要预构建的
|
||||
exclude: ['artalk'],
|
||||
},
|
||||
|
||||
// esbuild 配置
|
||||
esbuild: {
|
||||
// 生产环境移除 console 和 debugger
|
||||
drop: process.env.NODE_ENV === 'production' ? ['console', 'debugger'] : [],
|
||||
// 压缩选项
|
||||
legalComments: 'none',
|
||||
},
|
||||
|
||||
// CSS 配置
|
||||
css: {
|
||||
devSourcemap: true,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user