Skip to content

项目配置

为什么需要了解配置?

Nuxt 的理念是"约定优于配置"——大部分功能零配置就能用。但有些东西必须配置,比如:

  • API 的基础地址(开发环境和生产环境不同)
  • 数据库密钥等敏感信息(不能写死在代码里)
  • 第三方模块的启用(如 Pinia、图片优化等)
  • 不同页面使用不同的渲染策略

了解配置,你就掌握了 Nuxt 的"控制面板"。

nuxt.config.ts

Nuxt 的主配置文件,位于项目根目录:

ts
export default defineNuxtConfig({
  // 开发工具
  devtools: { enabled: true },

  // 模块
  modules: [
    '@pinia/nuxt',
    '@nuxt/image',
  ],

  // 运行时配置
  runtimeConfig: {
    // 服务端私有(不暴露给客户端)
    apiSecret: '',
    // 公共配置(暴露给客户端)
    public: {
      apiBase: process.env.API_BASE || '/api',
    },
  },

  // 应用配置
  app: {
    head: {
      title: '我的 Nuxt 应用',
      meta: [
        { name: 'description', content: 'Nuxt 4 应用' },
      ],
    },
  },

  // CSS
  css: ['~/app/assets/css/main.css'],

  // Vite 配置
  vite: {
    // 自定义 Vite 配置
  },

  // 兼容性日期
  compatibilityDate: '2025-07-15',
})

defineNuxtConfig 是什么?

它是 Nuxt 提供的辅助函数,为你提供:

  • TypeScript 类型提示(知道有哪些配置项)
  • 配置合并(多个来源的配置合并在一起)
  • 默认值填充(你不需要的配置项有合理的默认值)

虽然你可以直接 export default { ... }

但推荐用 defineNuxtConfig,因为它能帮你检查拼写错误和类型。

compatibilityDate 是什么?

它告诉 Nuxt 你期望使用哪个时间点的行为。Nuxt 不断进化,某些行为可能变化。设置这个日期可以确保你的项目行为稳定。一般设为项目创建日期即可。

runtimeConfig — 运行时配置

为什么需要 runtimeConfig?

你的项目在不同环境下需要不同的配置:

场景API 地址数据库密码
本地开发http://localhost:3000/apidev-password
测试环境https://staging.example.com/apistaging-password
生产环境https://api.example.com非常复杂的密码

你不可能为每个环境维护一份代码。runtimeConfig 让你一份代码,通过环境变量适配不同环境

配置层级

ts
export default defineNuxtConfig({
  runtimeConfig: {
    // ① 仅服务端可访问(不会发送到浏览器)
    dbUrl: '',           // 数据库连接字符串
    apiSecret: '',       // API 密钥

    // ② 客户端和服务端都可访问
    public: {
      apiBase: '/api',   // API 基础路径
      appName: 'MyApp',  // 应用名称
    },
  },
})

为什么要有"私有"和"公开"的区别?

在 SSR 模式下,Nuxt 会将数据发送到客户端。如果你把数据库密码放在 public 之外的地方,它不会被发送到浏览器,用户无法在开发者工具中看到。

配置位置服务端可访问客户端可访问典型用途
runtimeConfig.xxx数据库密码、API 密钥
runtimeConfig.public.xxxAPI 地址、应用名称

INFO

安全原则:永远不要把敏感信息(密钥、密码、token)放在 public 下面!

环境变量覆盖

运行时配置会被环境变量自动覆盖:

配置项环境变量示例
runtimeConfig.apiSecretNUXT_API_SECRETNUXT_API_SECRET=my-secret
runtimeConfig.public.apiBaseNUXT_PUBLIC_API_BASENUXT_PUBLIC_API_BASE=https://api.example.com
runtimeConfig.public.appNameNUXT_PUBLIC_APP_NAMENUXT_PUBLIC_APP_NAME=Nuxt4App

命名规则

NUXT_ + 配置路径(用 _ 连接,全部大写)

比如 runtimeConfig.public.apiBaseNUXT_PUBLIC_API_BASE

嵌套层级也支持:runtimeConfig.public.theme.primaryColorNUXT_PUBLIC_THEME_PRIMARY_COLOR

在代码中使用

ts
// 服务端代码(server/api/xxx.ts)
const config = useRuntimeConfig()
console.log(config.apiSecret)      // ✅ 可访问——有值
console.log(config.public.apiBase)  // ✅ 可访问

// 客户端代码(app/pages/xxx.vue)
const config = useRuntimeConfig()
console.log(config.apiSecret)      // ❌ undefined——安全,不会泄露到浏览器
console.log(config.public.apiBase)  // ✅ 可访问

为什么服务端能访问 apiSecret

客户端不能? Nuxt 在构建时就知道哪些配置是"私有的"。对于私有配置:

  • 服务端渲染时可以使用
  • 但不会包含在发送到浏览器的 JavaScript 中
  • 所以用户无论怎么看源码都找不到

.env 文件

env
# .env(项目根目录)
NUXT_API_SECRET=my-secret-key
NUXT_PUBLIC_API_BASE=https://api.example.com
NUXT_PUBLIC_APP_NAME=Nuxt4App

.env 文件的工作原理

  1. Nuxt 开发服务器启动时自动读取 .env 文件
  2. .env 中的变量会覆盖 nuxt.config.tsruntimeConfig 的默认值
  3. 生产环境通常在服务器上设置真正的环境变量(不用 .env

INFO

重要.env 文件不要提交到 Git!它可能包含敏感信息 确认 .gitignore 中有 .env

最佳实践

提供 .env.example 文件提交到 Git,列出需要的环境变量但不含真实值:

env
# .env.example
NUXT_API_SECRET=
NUXT_PUBLIC_API_BASE=/api
NUXT_PUBLIC_APP_NAME=MyApp

新成员克隆项目后,复制为 .env 并填入真实值即可。

app.config.ts — 应用配置

runtimeConfig 不同,app.config.ts 是在构建时确定的,可被运行时覆盖:

ts
// app/app.config.ts
export default defineAppConfig({
  theme: {
    primaryColor: '#00DC82',
    darkMode: false,
  },
  layout: {
    sidebarWidth: 240,
  },
})

在代码中使用

ts
const appConfig = useAppConfig()
console.log(appConfig.theme.primaryColor) // '#00DC82'

runtimeConfig vs app.config

特性runtimeConfigapp.config
暴露时机运行时构建时 + 运行时可覆盖
环境变量✅ 自动覆盖❌ 不支持
私有配置✅ 服务端独有❌ 全部公开
用途API 密钥、数据库地址主题色、UI 配置
修改后不需要重新构建需要重新构建
适合存放会随环境变化的内容基本不变的 UI 设置

选择原则

  • 需要不同环境不同值?→ runtimeConfig
  • 涉及敏感信息?→ runtimeConfig(非 public 部分)
  • 纯 UI 配置、主题相关?→ app.config
  • 不确定?→ 先用 runtimeConfig,它更灵活

nuxt.config.ts 常用配置项

ts
export default defineNuxtConfig({
  // 渲染模式
  ssr: true,                         // 默认 true,SSR 模式

  // 全局 CSS
  css: ['~/app/assets/css/main.css'],

  // 页面过渡
  pageTransition: { name: 'page', mode: 'out-in' },
  layoutTransition: { name: 'layout', mode: 'out-in' },

  // 路由规则
  routeRules: {
    '/admin/**': { ssr: false },      // 后台不走 SSR
    '/blog/**': { swr: 3600 },        // 博客页面缓存 1 小时
    '/api/**': { cors: true },        // API 允许跨域
  },

  // Nitro(服务端)配置
  nitro: {
    preset: 'node-cluster',           // 部署预设
  },

  // TypeScript
  typescript: {
    strict: true,                     // 严格模式
  },

  // 实验性特性
  experimental: {
    typedPages: true,                 // 类型化路由
  },
})

~ 路径别名是什么?

在 Nuxt 配置中,~ 代表项目根目录。所以 ~/app/assets/css/main.css 等于 <项目根目录>/app/assets/css/main.css

常用的路径别名:

别名指向
~@项目根目录
~~@@项目根目录(与 ~ 相同,用于区分)
#imports自动导入的模块

.nuxtrc 文件

.nuxtrc 是另一种配置语法,使用扁平的键值对格式:

bash
# .nuxtrc
modules[]=@pinia/nuxt
modules[]=@nuxt/image
devtools.enabled=true
  • 项目级:放在项目根目录
  • 用户级:放在 ~/.nuxtrc(全局生效)

什么时候用 .nuxtrc

当你想设置一些个人偏好(不影响项目的配置),放在 ~/.nuxtrc 中。比如你的全局 DevTools 偏好。项目级配置还是推荐用 nuxt.config.ts

.nuxtignore 文件

指定 Nuxt 在构建时忽略的文件:

bash
# .nuxtignore
# 忽略特定页面(不会生成路由)
app/pages/secret.vue
# 忽略特定组件(不会自动导入)
app/components/legacy/**
# 忽略特定布局
app/layouts/old-*.vue

.gitignore 的区别

  • .gitignore:Git 忽略,文件不会被提交到仓库
  • .nuxtignore:Nuxt 忽略,文件还在项目中但不参与构建

比如你有一个正在开发中的页面,不想让 Nuxt 生成路由,就在 .nuxtignore 中忽略它。

常见问题

修改了 nuxt.config.ts 但没生效

nuxt.config.ts 修改后需要重启开发服务器(Ctrl+C 然后重新 npm run dev)。

环境变量没生效

  1. 确认环境变量命名正确(NUXT_ 前缀 + 大写 + 下划线分隔)
  2. 确认 .env 文件在项目根目录
  3. 重启开发服务器
  4. 检查 .env 文件编码(应为 UTF-8,无 BOM)

runtimeConfig 在客户端读到 undefined

确认配置项在 public 下面。不在 public 下的配置不会发送到客户端(这是安全特性,不是 bug)。

知识脉络

text
第一个页面 → 你在这里:项目配置

               ├─→ 深入学习:渲染模式(03-核心概念)

               ├─→ 深入学习:路由规则(04-路由与导航)

               └─→ 深入学习:环境变量(18-部署上线)

基于 Nuxt 4 官方文档整理编写