Nuxt.js 配置文件最佳实践完全指南
nuxt.config.ts 概述
nuxt.config.ts 是 Nuxt.js 应用的核心配置文件,控制着应用的各个方面:构建行为、模块加载、运行时配置等。理解并正确配置这个文件,是开发高质量 Nuxt 应用的基础。
nuxt.config.ts 的作用范围:
┌─────────────────────────────────────────────────────────────┐
│ nuxt.config.ts │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 应用基础 │ │ 模块系统 │ │ 构建配置 │ │
│ │ - app │ │ - modules │ │ - vite │ │
│ │ - ssr │ │ - extends │ │ - nitro │ │
│ │ - devtools │ │ - plugins │ │ - postcss │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 路由配置 │ │ 运行时配置 │ │ 实验性功能 │ │
│ │ - router │ │ -runtimeConfig│ │ - experimental │ │
│ │ - pages │ │ - appConfig│ │ - features │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
基础配置结构
最小配置
// nuxt.config.ts
export default defineNuxtConfig({
// 兼容性日期
compatibilityDate: '2024-12-24',
// 开发工具
devtools: { enabled: true }
})
完整的生产配置框架
// nuxt.config.ts
export default defineNuxtConfig({
// 兼容性版本
compatibilityDate: '2024-12-24',
// 开发工具
devtools: { enabled: process.env.NODE_ENV !== 'production' },
// 应用配置
app: {},
// 模块
modules: [],
// 运行时配置
runtimeConfig: {},
// Vite 配置
vite: {},
// Nitro 服务器配置
nitro: {},
// 路由配置
routeRules: {},
// 实验性功能
experimental: {}
})
应用配置(app)
基础 App 配置
export default defineNuxtConfig({
app: {
// HTML head 配置
head: {
charset: 'utf-8',
viewport: 'width=device-width, initial-scale=1',
title: '我的网站',
titleTemplate: '%s - 我的网站',
// Meta 标签
meta: [
{ name: 'description', content: '网站描述' },
{ name: 'theme-color', content: '#ffffff' },
{ property: 'og:type', content: 'website' },
{ property: 'og:site_name', content: '我的网站' }
],
// Link 标签
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'apple-touch-icon', href: '/apple-touch-icon.png' },
{ rel: 'manifest', href: '/manifest.json' },
// 预连接优化
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{ rel: 'dns-prefetch', href: 'https://api.example.com' }
],
// Script 标签
script: [
// 分析脚本(异步加载)
{
src: 'https://analytics.example.com/script.js',
async: true,
defer: true
}
],
// HTML 属性
htmlAttrs: {
lang: 'zh-CN'
},
// Body 属性
bodyAttrs: {
class: 'antialiased'
}
},
// 页面过渡动画
pageTransition: {
name: 'page',
mode: 'out-in'
},
// 布局过渡动画
layoutTransition: {
name: 'layout',
mode: 'out-in'
},
// 基础路径(用于子目录部署)
baseURL: '/',
// CDN URL
cdnURL: process.env.CDN_URL || ''
}
})
动态 Head 配置
// 使用函数动态生成 head
export default defineNuxtConfig({
app: {
head: () => {
const isProd = process.env.NODE_ENV === 'production';
return {
title: isProd ? '生产环境' : '开发环境',
meta: [
// 生产环境添加额外的安全头
...(isProd ? [
{ 'http-equiv': 'X-UA-Compatible', content: 'IE=edge' },
{ name: 'robots', content: 'index, follow' }
] : [
{ name: 'robots', content: 'noindex, nofollow' }
])
]
};
}
}
})
模块配置(modules)
常用模块配置
export default defineNuxtConfig({
modules: [
// UI 框架
'@nuxt/ui',
// 图片优化
'@nuxt/image',
// 内容管理
'@nuxt/content',
// SEO
'@nuxtjs/seo',
// 国际化
'@nuxtjs/i18n',
// 分析
'@nuxtjs/plausible',
// 状态管理
'@pinia/nuxt',
// 自定义配置的模块
['@nuxtjs/google-fonts', {
families: {
'Inter': [400, 500, 600, 700]
},
display: 'swap',
prefetch: true,
preconnect: true
}]
]
})
模块选项的最佳实践
export default defineNuxtConfig({
modules: [
'@nuxt/image',
'@nuxt/content',
'@nuxtjs/i18n'
],
// 推荐:使用顶级配置而不是内联配置
// 这样更清晰,也便于类型推断
image: {
// 图片提供商
provider: 'ipx',
// 图片质量
quality: 80,
// 预设
presets: {
avatar: {
modifiers: {
format: 'webp',
width: 100,
height: 100,
fit: 'cover'
}
},
thumbnail: {
modifiers: {
format: 'webp',
width: 300,
height: 200,
fit: 'cover'
}
}
},
// 屏幕断点
screens: {
xs: 320,
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
xxl: 1536
}
},
content: {
// 内容目录
sources: {
content: {
driver: 'fs',
base: './content'
}
},
// Markdown 配置
markdown: {
toc: { depth: 3 },
remarkPlugins: [],
rehypePlugins: []
},
// 高亮配置
highlight: {
theme: 'github-dark',
langs: ['javascript', 'typescript', 'vue', 'css', 'html', 'json']
}
},
i18n: {
locales: [
{ code: 'zh', name: '中文', file: 'zh.json' },
{ code: 'en', name: 'English', file: 'en.json' }
],
defaultLocale: 'zh',
lazy: true,
langDir: 'locales/',
strategy: 'prefix_except_default',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
fallbackLocale: 'zh'
}
}
})
运行时配置(runtimeConfig)
环境变量与运行时配置
export default defineNuxtConfig({
runtimeConfig: {
// 仅服务端可访问的配置
// 敏感信息放这里
apiSecret: process.env.API_SECRET,
databaseUrl: process.env.DATABASE_URL,
jwtSecret: process.env.JWT_SECRET,
// 第三方服务密钥
stripe: {
secretKey: process.env.STRIPE_SECRET_KEY
},
// 邮件服务
mail: {
host: process.env.MAIL_HOST,
port: process.env.MAIL_PORT,
user: process.env.MAIL_USER,
password: process.env.MAIL_PASSWORD
},
// 公开的配置(客户端也可访问)
public: {
// 网站 URL
siteUrl: process.env.SITE_URL || 'http://localhost:3000',
// API 基础路径
apiBase: process.env.API_BASE || '/api',
// 公开的第三方服务 ID
googleAnalyticsId: process.env.GA_ID,
stripePublicKey: process.env.STRIPE_PUBLIC_KEY,
// 功能开关
features: {
enableComments: process.env.ENABLE_COMMENTS === 'true',
enableNewsletter: process.env.ENABLE_NEWSLETTER === 'true'
}
}
}
})
在代码中使用运行时配置
// 在 Vue 组件中
<script setup lang="ts">
const config = useRuntimeConfig()
// 客户端和服务端都可以访问
console.log(config.public.siteUrl)
console.log(config.public.apiBase)
// 仅服务端可以访问(在服务端代码中)
// console.log(config.apiSecret) // 仅在服务端有效
</script>
// 在服务端 API 中
// server/api/example.ts
export default defineEventHandler((event) => {
const config = useRuntimeConfig(event)
// 可以访问私有配置
const secret = config.apiSecret
const dbUrl = config.databaseUrl
// 也可以访问公开配置
const siteUrl = config.public.siteUrl
return { message: 'ok' }
})
Vite 配置
构建优化
export default defineNuxtConfig({
vite: {
// 构建目标
build: {
// 浏览器兼容性
target: 'es2020',
// CSS 代码分割
cssCodeSplit: true,
// 分块策略
rollupOptions: {
output: {
manualChunks: {
// 第三方库分离
'vendor-vue': ['vue', 'vue-router'],
'vendor-utils': ['lodash-es', 'date-fns'],
'vendor-ui': ['@headlessui/vue', '@heroicons/vue']
}
}
},
// 压缩选项
minify: 'terser',
terserOptions: {
compress: {
drop_console: process.env.NODE_ENV === 'production',
drop_debugger: true
}
}
},
// CSS 配置
css: {
preprocessorOptions: {
scss: {
additionalData: `
@use "@/assets/styles/variables" as *;
@use "@/assets/styles/mixins" as *;
`
}
}
},
// 优化依赖预构建
optimizeDeps: {
include: [
'vue',
'vue-router',
'@vueuse/core',
'pinia'
],
exclude: [
'some-heavy-package'
]
},
// 服务器配置
server: {
hmr: {
overlay: true
},
watch: {
// 忽略某些文件的监听
ignored: ['**/node_modules/**', '**/dist/**']
}
},
// 插件
plugins: [
// 可以添加 Vite 插件
]
}
})
别名配置
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
const currentDir = dirname(fileURLToPath(import.meta.url))
export default defineNuxtConfig({
alias: {
'@': join(currentDir, './'),
'@components': join(currentDir, './components'),
'@composables': join(currentDir, './composables'),
'@utils': join(currentDir, './utils'),
'@assets': join(currentDir, './assets'),
'@types': join(currentDir, './types')
}
})
Nitro 服务器配置
基础服务器配置
export default defineNuxtConfig({
nitro: {
// 部署预设
preset: 'node-server', // 或 'vercel', 'netlify', 'cloudflare' 等
// 压缩响应
compressPublicAssets: true,
// 存储配置
storage: {
cache: {
driver: 'redis',
url: process.env.REDIS_URL
},
data: {
driver: 'fs',
base: './data'
}
},
// 定时任务
scheduledTasks: {
'0 0 * * *': ['cleanup:old-data']
},
// 路由规则
routeRules: {
// 预渲染静态页面
'/': { prerender: true },
'/about': { prerender: true },
'/blog/**': { prerender: true },
// API 缓存
'/api/products': { cache: { maxAge: 60 * 60 } }, // 1小时
'/api/categories': { cache: { maxAge: 60 * 60 * 24 } }, // 1天
// SWR 缓存策略
'/api/user': {
cache: {
swr: true,
maxAge: 60,
staleMaxAge: 60 * 60
}
},
// 代理
'/legacy-api/**': { proxy: 'https://old-api.example.com/**' },
// 重定向
'/old-page': { redirect: '/new-page' },
// CORS
'/api/**': {
cors: true,
headers: {
'Access-Control-Allow-Origin': '*'
}
}
},
// 实验性功能
experimental: {
// 启用 WebSocket
websocket: true,
// 任务队列
tasks: true
}
}
})
预渲染配置
export default defineNuxtConfig({
nitro: {
prerender: {
// 要预渲染的路由
routes: [
'/',
'/about',
'/contact',
'/pricing'
],
// 爬取发现的链接
crawlLinks: true,
// 忽略某些路由
ignore: [
'/admin',
'/api'
],
// 并发数
concurrency: 10,
// 失败时的行为
failOnError: process.env.NODE_ENV === 'production'
}
},
// 路由规则中的预渲染
routeRules: {
// 动态路由预渲染
'/products/**': { prerender: true },
'/blog/**': { prerender: true }
}
})
环境特定配置
使用 $env 条件配置
export default defineNuxtConfig({
// 基础配置
devtools: { enabled: true },
// 开发环境特定配置
$development: {
devtools: { enabled: true },
vite: {
server: {
hmr: {
overlay: true
}
}
}
},
// 生产环境特定配置
$production: {
devtools: { enabled: false },
app: {
head: {
script: [
// 只在生产环境加载分析脚本
{ src: 'https://analytics.example.com/script.js', async: true }
]
}
},
nitro: {
compressPublicAssets: true
}
},
// 测试环境
$test: {
ssr: false
}
})
基于环境变量的配置
const isDev = process.env.NODE_ENV !== 'production'
const isPreview = process.env.NUXT_ENV === 'preview'
export default defineNuxtConfig({
ssr: !isDev || isPreview,
sourcemap: isDev ? 'hidden' : false,
modules: [
'@nuxt/ui',
// 开发时启用的模块
...(isDev ? ['@nuxt/devtools'] : []),
// 生产时启用的模块
...(!isDev ? ['@nuxtjs/plausible'] : [])
],
vite: {
build: {
sourcemap: isDev,
minify: !isDev
}
}
})
性能优化配置
完整的性能优化配置
export default defineNuxtConfig({
// 启用实验性功能以提升性能
experimental: {
// 内联样式
inlineSSRStyles: true,
// 组件岛屿
componentIslands: true,
// Payload 提取
payloadExtraction: true,
// 视图过渡 API
viewTransition: true,
// 渲染 JSON Payload
renderJsonPayloads: true
},
// Vite 性能配置
vite: {
build: {
// 代码分割
cssCodeSplit: true,
rollupOptions: {
output: {
// 优化分块
manualChunks(id) {
if (id.includes('node_modules')) {
// 核心依赖
if (id.includes('vue') || id.includes('pinia')) {
return 'vendor-core'
}
// UI 库
if (id.includes('@headlessui') || id.includes('@heroicons')) {
return 'vendor-ui'
}
// 工具库
return 'vendor-utils'
}
}
}
}
},
// 预构建优化
optimizeDeps: {
include: ['vue', 'pinia', '@vueuse/core']
}
},
// Nitro 性能配置
nitro: {
compressPublicAssets: {
gzip: true,
brotli: true
},
// 静态资源缓存
publicAssets: [{
dir: 'public',
maxAge: 60 * 60 * 24 * 365, // 1年
baseURL: '/'
}],
// 预渲染
prerender: {
crawlLinks: true,
concurrency: 10
}
},
// 路由缓存规则
routeRules: {
// 静态页面
'/': { prerender: true },
// API 缓存
'/api/static/**': {
cache: { maxAge: 60 * 60 * 24 }
},
// CDN 缓存
'/_nuxt/**': {
headers: {
'cache-control': 'public, max-age=31536000, immutable'
}
}
}
})
懒加载和代码分割
export default defineNuxtConfig({
// 组件自动导入配置
components: {
dirs: [
{
path: '~/components',
// 全局组件(立即加载)
global: false
},
{
path: '~/components/global',
global: true
}
]
},
// 插件配置
plugins: [
// 客户端插件(懒加载)
{ src: '~/plugins/analytics.client.ts', mode: 'client' },
// 服务端插件
{ src: '~/plugins/auth.server.ts', mode: 'server' }
],
// 实验性:组件岛屿
experimental: {
componentIslands: true
}
})
调试和开发体验
开发工具配置
export default defineNuxtConfig({
// DevTools
devtools: {
enabled: true,
timeline: {
enabled: true
}
},
// 开发服务器
devServer: {
port: 3000,
host: '0.0.0.0',
// HTTPS(本地开发)
https: false
},
// TypeScript 配置
typescript: {
strict: true,
typeCheck: true,
shim: false
},
// 源码映射
sourcemap: {
server: true,
client: true
},
// 调试信息
debug: process.env.DEBUG === 'true',
// 日志级别
logLevel: process.env.DEBUG === 'true' ? 'verbose' : 'info'
})
安全配置
安全头和 CSP
export default defineNuxtConfig({
// 安全模块
modules: ['nuxt-security'],
security: {
headers: {
// 内容安全策略
contentSecurityPolicy: {
'base-uri': ["'self'"],
'default-src': ["'self'"],
'script-src': ["'self'", "'unsafe-inline'", 'https://trusted-cdn.com'],
'style-src': ["'self'", "'unsafe-inline'"],
'img-src': ["'self'", 'data:', 'https:'],
'font-src': ["'self'", 'https://fonts.gstatic.com'],
'connect-src': ["'self'", 'https://api.example.com'],
'frame-ancestors': ["'none'"]
},
// 其他安全头
crossOriginEmbedderPolicy: 'require-corp',
crossOriginOpenerPolicy: 'same-origin',
crossOriginResourcePolicy: 'same-origin',
permissionsPolicy: {
camera: [],
microphone: [],
geolocation: []
},
strictTransportSecurity: {
maxAge: 31536000,
includeSubdomains: true,
preload: true
},
xContentTypeOptions: 'nosniff',
xFrameOptions: 'DENY',
xXSSProtection: '1; mode=block'
},
// 请求大小限制
requestSizeLimiter: {
maxRequestSizeInBytes: 2000000, // 2MB
maxUploadFileRequestInBytes: 8000000 // 8MB
},
// 速率限制
rateLimiter: {
tokensPerInterval: 100,
interval: 60000 // 1分钟
}
}
})
完整的生产配置示例
// nuxt.config.ts
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
const currentDir = dirname(fileURLToPath(import.meta.url))
const isDev = process.env.NODE_ENV !== 'production'
export default defineNuxtConfig({
// 基础配置
compatibilityDate: '2024-12-24',
devtools: { enabled: isDev },
// 应用配置
app: {
head: {
charset: 'utf-8',
viewport: 'width=device-width, initial-scale=1',
title: '我的应用',
titleTemplate: '%s - 我的应用',
htmlAttrs: { lang: 'zh-CN' },
meta: [
{ name: 'description', content: '应用描述' },
{ name: 'theme-color', content: '#4f46e5' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
pageTransition: { name: 'page', mode: 'out-in' }
},
// 模块
modules: [
'@nuxt/ui',
'@nuxt/image',
'@nuxt/content',
'@pinia/nuxt',
'@vueuse/nuxt',
'@nuxtjs/i18n'
],
// 运行时配置
runtimeConfig: {
apiSecret: process.env.API_SECRET,
public: {
siteUrl: process.env.SITE_URL || 'http://localhost:3000',
apiBase: process.env.API_BASE || '/api'
}
},
// Vite
vite: {
build: {
target: 'es2020',
cssCodeSplit: true,
rollupOptions: {
output: {
manualChunks: {
'vendor-vue': ['vue', 'vue-router', 'pinia'],
'vendor-utils': ['@vueuse/core']
}
}
}
},
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "@/assets/styles/variables" as *;'
}
}
}
},
// Nitro
nitro: {
compressPublicAssets: true,
prerender: {
routes: ['/', '/about'],
crawlLinks: true
}
},
// 路由规则
routeRules: {
'/': { prerender: true },
'/api/**': { cors: true },
'/_nuxt/**': {
headers: { 'cache-control': 'public, max-age=31536000, immutable' }
}
},
// 实验性功能
experimental: {
payloadExtraction: true,
renderJsonPayloads: true,
viewTransition: true
},
// TypeScript
typescript: {
strict: true,
typeCheck: isDev
}
})
最佳实践总结
nuxt.config.ts 最佳实践:
组织结构:
✓ 按功能区块组织配置
✓ 使用顶级模块配置而非内联配置
✓ 敏感信息放在 runtimeConfig 中
✓ 公开配置放在 runtimeConfig.public 中
性能优化:
✓ 启用适当的实验性功能
✓ 配置合理的代码分割策略
✓ 使用预渲染加速静态页面
✓ 配置适当的缓存策略
环境管理:
✓ 使用 $development/$production 条件配置
✓ 通过环境变量控制功能开关
✓ 生产环境禁用调试工具
✓ 开发环境启用详细日志
安全性:
✓ 配置安全头(CSP 等)
✓ 私密信息不暴露到客户端
✓ 使用 HTTPS
✓ 配置请求限制和速率限制
可维护性:
✓ 添加必要的注释
✓ 使用 TypeScript 获取类型提示
✓ 定期更新依赖和配置
✓ 保持配置文件简洁清晰
正确配置 nuxt.config.ts 是构建高质量 Nuxt.js 应用的基础。随着项目的发展,定期审查和优化配置文件,确保它始终符合项目的需求。


