import vuetify, { transformAssetUrls } from "vite-plugin-vuetify";
import versionUpdatePlugin from "./plugins/versionUpdatePlugin";
import viteCompression from "vite-plugin-compression";
import cssnano from "cssnano";
// PWA Config
const shortTitle = "Xescort.net";
const description =
"The best incall & outcall independent escort, 100% real escort and real-name verification, the best dating experience, regardless of gender, age, region or other more requirements can be met.";
const themeColor = "#4f46e5";
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
modules: [
"@nuxtjs/tailwindcss",
"@vite-pwa/nuxt",
"@pinia/nuxt",
"@pinia-plugin-persistedstate/nuxt",
"@nuxt/image",
"nuxt-vitalizer",
async (options, nuxt) => {
nuxt.hooks.hook("vite:extendConfig", (config) => {
config.plugins ||= [];
config.plugins.push(vuetify());
});
},
],
postcss: {
plugins: {
"@fullhuman/postcss-purgecss": {
content: ["./pages/**/*.vue", "./components/**/*.vue", "./layouts/**/*.vue", "./app.vue"],
safelist: [
/^v-/, // 保留所有 Vuetify 类名
/^mdi-/,
/--text$/,
/--bg$/,
/^theme--/,
],
},
},
},
image: {
formats: ["webp", "avif"],
screens: { xs: 320, sm: 640, md: 768 },
presets: {
cover: { modifiers: { fit: "cover", format: "webp" } },
},
// domains: ["https://assets.xescort.net"],
},
build: {
analyze: {
analyzerMode: "static",
},
transpile: ["vuetify", "@fancyapps/ui", "@nuxt/image"],
},
ssr: true,
// import styles
experimental: {
externalVue: false,
},
css: [
"vue-snap/dist/vue-snap.css",
"@/assets/main.scss",
"@/assets/icons/iconfont.css",
"@/assets/icons/bootstrap-icons.css",
],
devtools: { enabled: true },
routeRules: {
"/**": {
appMiddleware: ["cache"],
},
},
// enable takeover mode
typescript: { shim: false },
nitro: {
compressPublicAssets: true,
prerender: {
// crawlLinks: true, // 自动爬取页面链接
routes: [], // 入口页面
ignore: ["/_ipx/**"] /* dynamic routes */,
},
routeRules: {
"/**": {
// cache: false,
// headers: {
// "Cache-Control": "no-cache, no-store, must-revalidate",
// },
},
"/api/**": {
cache: {
swr: true,
maxAge: 60,
},
}, // 60秒后重新验证
"/": {
prerender: false, // 预渲染首页
isr: 3600,
// swr: 60,
headers: {
"Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时
},
},
"/categories/[type]/[args]": {
prerender: false, // 预渲染分类页面
isr: 3600,
swr: 600,
headers: {
"Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时
},
},
"/search": {
prerender: false, // 预渲染搜索页面
isr: 3600,
swr: 600,
headers: {
"Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时
},
},
"/details/[tag]/[identity]": {
prerender: false,
isr: 3600,
swr: 600,
headers: {
"Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时
},
},
"/escorts/[country]": {
prerender: false, // 预渲染所有 escort 页面
isr: 3600,
swr: 600,
headers: {
"Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时
},
},
"/escorts/[country]/[state]": {
prerender: false, // 预渲染所有 escort 页面
isr: 3600,
swr: 600,
headers: {
"Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时
},
},
"/escorts/[country]/[state]/[city]": {
prerender: false, // 预渲染所有 escort 页面
isr: 3600,
swr: 600,
headers: {
"Cache-Control": "public, max-age=3600, s-maxage=3600", // 缓存1小时
},
},
},
},
// Based on docs found here - https://vuetifyjs.com/en/getting-started/installation/#using-nuxt-3
vite: {
css: {
preprocessorOptions: {
scss: {
api: "modern-compiler",
},
},
// postcss: {
// plugins: [
// cssnano({
// preset: ["default", { discardComments: { removeAll: true } }],
// }),
// ],
// },
},
optimizeDeps: {
include: ["vuetify", "@fancyapps/ui"],
},
build: {
modulePreload: false,
sourcemap: false,
emptyOutDir: true, // 强制清空输出目录
rollupOptions: {
output: {
format: "es",
manualChunks: (id) => {
if (id.includes(".scss")) {
return "style";
}
if (id.includes("node_modules")) {
return "vendor";
}
},
},
},
},
plugins: [
viteCompression({
algorithm: "gzip",
ext: ".gz",
threshold: 2048, // Only compress files larger than 10KB
}),
versionUpdatePlugin(),
vuetify({
autoImport: true,
}),
],
vue: {
template: {
transformAssetUrls,
},
},
// server: {
// // host: "0.0.0.0", // Removed as it is not allowed in the current type
// proxy: {
// "/api": {
// target: "https://www.xkwsb.top",
// changeOrigin: true,
// // rewrite: (path) => path.replace(/^\/api/, ""),
// },
// },
// },
define: {
"process.env.DEBUG": false,
},
},
// devServer: {
// https: {
// cert: "./certs/cert.pem",
// key: "./certs/dev.pem",
// },
// },
runtimeConfig: {
isServer: true,
baseUrl: process.env.NUXT_BASE_URL,
port: process.env.PORT || "8000",
public: {
wsUrl: process.env.NUXT_WS_URL,
chatWs: process.env.NUXT_CHAT_WS,
chatApi: process.env.NUXT_CHAT_API,
port: process.env.PORT || "8000",
baseUrl: process.env.NUXT_BASE_URL,
gClient: process.env.GOOGLE_CLIENT_ID,
},
},
vitalizer: {
delayHydration: {
hydrateOnEvents: ["click", "touchstart"],
idleCallbackTimeout: 2000,
postIdleTimeout: 1000,
},
disablePrefetchLinks: "dynamicImports",
disablePreloadLinks: true,
disableStylesheets: "entry",
},
app: {
head: {
htmlAttrs: {
lang: "en",
},
meta: [
{ name: "theme-color", content: themeColor },
{ name: "mobile-web-app-capable", content: "yes" },
{ name: "rating", content: "adult" },
{ name: "robots", content: "noarchive" },
{ name: "referrer", content: "no-referrer" },
],
link: [
{
rel: "stylesheet",
href: "https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css",
},
{ rel: "icon", type: "image/x-icon", href: "/icons/favicon.ico" },
{ rel: "apple-touch-icon", href: "/icons/apple-touch-icon.png" },
{ rel: "alternate", href: "https://www.xescort.net", hreflang: "x-default" },
{ rel: "preconnect", href: "https://api.iconify.design" },
{ rel: "preconnect", href: "https://assets.xescort.net" },
{ rel: "dns-prefetch", href: "https://api.iconify.design" },
],
// // DNS 预解析 Vue 官方 CDN
// { rel: "dns-prefetch", href: "https://unpkg.com" },
// // 预解析常用 CDN(按需添加)
// { rel: "dns-prefetch", href: "https://cdn.jsdelivr.net" },
// { rel: "dns-prefetch", href: "https://fonts.googleapis.com" },
// // 推荐同时配置 TCP 预连接
// { rel: "preconnect", href: "https://unpkg.com", crossorigin: "anonymous" },
script: [
// {
// src: "https://unpkg.com/vue@3/dist/vue.global.prod.js",
// defer: true, // 异步加载
// tagPosition: "bodyClose",
// },
// {
// src: "https://www.googletagmanager.com/gtag/js?id=G-5VCS4RBFF2",
// tagPosition: "bodyClose",
// tagPriority: "low",
// },
// {
// type: "text/javascript",
// innerHTML:
// "window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-5VCS4RBFF2');",
// tagPosition: "bodyClose",
// tagPriority: "low",
// },
],
},
},
pwa: {
includeAssets: ["favicon.ico", "*.txt"],
manifest: {
name: shortTitle,
short_name: shortTitle,
description: description,
theme_color: themeColor,
lang: "en",
background_color: "#ffffff",
icons: [
{
src: "/icons/pwa-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "any",
},
{
src: "/icons/pwa-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "any",
},
{
src: "/icons/pwa-maskable-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "maskable",
},
{
src: "/icons/pwa-maskable-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
],
},
workbox: {
globPatterns: ["**/*.{js,css,html,png,webp,gif,jpg,jpeg,svg,ico}"],
globIgnores: ["**/icons/iconfont.css", "**/icons/bootstrap-icons.css"],
runtimeCaching: [
{
urlPattern: ({ request }) => request.destination === "image",
handler: "CacheFirst",
options: {
cacheName: "images",
expiration: {
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
},
},
},
{
urlPattern: ({ request }) =>
request.destination === "script" || request.destination === "style",
handler: "StaleWhileRevalidate",
options: {
cacheName: "scripts-styles",
expiration: {
maxEntries: 20,
maxAgeSeconds: 1 * 24 * 60 * 60, // 1 days
},
},
},
],
},
},
compatibilityDate: "2025-08-12",
});
帮我分析下这个nuxt3的配置文件 修改哪些地方可以优化项目
最新发布