Skip to content

构建命令

构建前确认

在运行构建命令之前,确保:

  1. 所有功能正常npm run dev 下没有报错
  2. 类型检查通过npx nuxt typecheck(可选但推荐)
  3. 环境变量就绪:确认 .env 或环境变量已配置

nuxt build

构建生产版本:

bash
npm run build
# 或
npx nuxt build

什么时候用 nuxt build

你的应用需要服务端渲染(SSR)或包含 API 路由时使用。构建产物包含服务端代码和客户端代码,需要 Node.js 环境运行。

构建产物详解

输出到 .output/ 目录:

text
.output/
├── public/              # 客户端资源
│   ├── _nuxt/           # JS、CSS、图片(文件名含哈希,可永久缓存)
│   │   ├── entry.xxx.js
│   │   ├── page-about.xxx.js
│   │   └── ...
│   └── __payload.json   # SSR Payload(可选)
├── server/              # 服务端代码
│   ├── index.mjs        # 服务入口文件
│   ├── chunks/          # 服务端代码分块
│   └── package.json     # 服务端依赖声明
└── nitro.json           # Nitro 部署配置

每个目录的作用

目录内容部署时需要?
public/浏览器下载的所有文件✅ 需要,作为静态资源
server/Node.js 服务端代码✅ 需要(SSR 模式)
nitro.json部署配置信息✅ 需要

INFO

.output/ 目录不应提交到 Git 它是构建产物,每次 nuxt build 都会重新生成。将其加入 .gitignore

常用选项

bash
# 指定预设
NUXT_NITRO_PRESET=vercel npx nuxt build

# 构建分析(v4.4+)
npx nuxt build --profile

# 详细分析
npx nuxt build --profile=verbose

构建分析(v4.4+)

为什么需要构建分析?

当构建速度慢或产物体积过大时,分析报告帮你定位瓶颈。

生成三种性能报告:

text
.nuxt/
├── perf-trace.json        # Chrome Trace 格式
├── perf-report.json       # JSON 报告
└── nuxt-build.cpuprofile  # CPU Profile
  • Chrome Trace:在 chrome://tracing 中打开,查看每个构建步骤的耗时
  • CPU Profile:在 Chrome DevTools → Performance 中打开,查看 CPU 热点

nuxt preview

构建后在本地预览生产版本

bash
npm run preview
# 或
npx nuxt preview

nuxt preview 做了什么?

  1. 启动一个本地服务器运行 .output/ 中的构建产物
  2. 模拟生产环境运行(代码压缩、优化后的版本)
  3. 默认在 http://localhost:3000 启动

为什么构建后要预览?

问题只在 dev 模式测试在 preview 模式测试
代码压缩导致的 bug❌ 发现不了(dev 模式不压缩)✅ 能发现
CSS/JS 体积问题❌ 看不出(没有打包)✅ 可以分析
SSR 数据传递问题❌ 可能遗漏✅ 更接近生产
路由规则不生效❌ dev 模式行为不同✅ 能验证

最佳实践

每次构建后用 nuxt preview 快速验证,确保生产版本没有明显问题,再进行部署。

preview 常见问题

bash
# 端口被占用
npx nuxt preview --port 3001

# 预览 SSG 站点
npx nuxt preview  # 先 nuxt generate,再 preview

nuxt generate

生成静态站点(SSG):

bash
npm run generate
# 或
npx nuxt generate

什么时候用 nuxt generate

你的应用是纯内容站点(博客、文档、落地页),不需要服务端渲染和 API 路由时使用。产物是纯 HTML/CSS/JS 文件,可以部署到任何静态托管平台。

预渲染所有页面为 HTML 文件:

text
.output/
└── public/
    ├── index.html
    ├── about/
    │   └── index.html
    ├── blog/
    │   ├── first-post/
    │   │   └── index.html
    │   └── index.html
    ├── _payload.json
    └── _nuxt/          # JS、CSS、图片

nuxt generate 的工作过程

  1. 先执行 nuxt build
  2. 然后对每个路由执行一次 SSR,生成 HTML 文件
  3. 最终产物只有 public/ 目录,不需要 Node.js 服务器

INFO

nuxt generate 的限制:

  • 它会尝试预渲染所有页面
  • 如果页面依赖运行时数据(如用户登录状态),预渲染可能失败
  • 动态路由(如 [id].vue)需要在 nitro.prerender.routes 中手动列出,或配置 crawlLinks
  • 页面数量很多时(如几千篇文章),构建会非常慢

替代方案

如果页面太多或有动态内容,用 nuxt build + ISR/SWR 缓存策略,只预渲染关键页面。

与 nuxt build 的区别

命令输出需要服务器适用场景部署成本
nuxt build服务端 + 客户端✅ 需要SSR 应用、有 API 路由需要服务器(VPS/云)
nuxt generate纯静态文件❌ 不需要静态站点、纯内容展示免费(GitHub Pages 等)

简单判断

如果你的项目有 server/api/ 目录或需要 SSR → 用 nuxt build。如果是纯展示站点 → 用 nuxt generate

动态路由的预渲染

nuxt generate 不会自动发现动态路由(如 [id].vue),需要手动指定:

ts
export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: [
        '/blog/post-1',
        '/blog/post-2',
        '/blog/post-3',
        // 或者用 crawlLinks 自动发现页面中的链接
      ],
      crawlLinks: true,  // 自动爬取页面中的链接
    },
  },
})

crawlLinks 做了什么?

渲染每个页面后,扫描页面中的 <a> 标签,发现新路由就继续渲染。这样就不需要手动列出所有路由。但如果某些页面没有链接指向(如只有通过搜索才能访问),它们不会被预渲染。

完整的构建-预览-部署流程

bash
开发阶段                     验证阶段                    部署阶段
────────                     ────────                    ────────
npm run dev    nuxt build    nuxt preview    部署到服务器
(开发调试)          (构建生产版本)      (本地验证)          (上线)
bash
# 1. 开发
npm run dev

# 2. 类型检查(可选但推荐)
npx nuxt typecheck

# 3. 构建
npm run build

# 4. 本地预览验证
npm run preview

# 5. 确认无误后部署
# (取决于部署平台,详见 03-部署平台)

Nitro 预设

通过预设控制部署目标,Nitro 会为不同平台生成适配的代码:

ts
export default defineNuxtConfig({
  nitro: {
    preset: 'node-server',  // 预设名称
  },
})
预设说明适用场景构建产物特点
node-serverNode.js 服务器(默认)自建服务器、VPS独立 Node.js 进程
node-clusterNode.js 集群多核服务器、高并发自动利用所有 CPU 核心
vercelVercel快速部署、免费起步Vercel Serverless Functions
netlifyNetlify静态站点 + 轻量 SSRNetlify Functions
cloudflare-pagesCloudflare Pages边缘计算、全球加速Workers 运行时
deno-deployDeno DeployDeno 运行时Deno 运行时
bunBun 运行时高性能 Node 替代Bun 运行时
static纯静态GitHub Pages、S3 托管纯静态文件

TIP

也可以通过环境变量指定预设:NITRO_PRESET=vercel nuxt build 适合 CI/CD 环境中动态切换

预设如何影响构建?

不同预设会生成不同的服务入口文件(server/index.mjs),但你的业务代码(server/api/server/middleware/ 等)不变。这就是 Nitro "一次构建,处处部署"的核心。

构建优化

1. 拆分 vendor 包

ts
export default defineNuxtConfig({
  vite: {
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            'vendor': ['vue', 'vue-router'],  // 不常变化的库单独打包
          },
        },
      },
    },
  },
})

为什么拆分 vendor?

  • vuevue-router 等库很少变化
  • 单独打包后,浏览器可以长期缓存这些文件
  • 你的业务代码变化时,用户只需重新下载业务代码的 chunk
  • 而不是整个 bundle 都重新下载

2. 路由规则缓存

ts
export default defineNuxtConfig({
  routeRules: {
    '/': { swr: 3600 },       // 首页缓存 1 小时
    '/blog/**': { isr: 60 },  // 博客每分钟重新生成
  },
})

缓存策略选择

  • SWR(Stale-While-Revalidate):先返回旧缓存,后台刷新。用户始终能立即看到内容,但可能看到稍旧的数据
  • ISR(Incremental Static Regeneration):缓存过期后重新生成。数据更准确,但过期后用户可能短暂等待
  • prerender:构建时生成。最简单,但数据不更新

3. Payload 优化

ts
export default defineNuxtConfig({
  experimental: {
    payloadExtraction: 'client',
  },
})

payloadExtraction 的三个值

行为适用场景
false(默认)Payload 内联在 HTML 中小型应用,Payload 不大
'client'Payload 内联 + 生成独立文件 + LRU 缓存中大型应用(推荐)
'server'仅在服务端提取特殊场景

'client' 模式的好处

  1. 首次访问:Payload 内联在 HTML 中(快速渲染)
  2. 客户端导航:从独立文件加载 Payload(可被浏览器缓存)
  3. LRU 缓存:服务端缓存已渲染的 Payload(减少重复计算)

4. 按需加载

vue
<!-- 懒加载大组件 -->
<LazyHeavyComponent v-if="showHeavy" />

<!-- 懒加载图片 -->
<NuxtImg loading="lazy" />

常见问题

问题原因解决方案
构建内存溢出(OOM)项目过大设置 NODE_OPTIONS=--max-old-space-size=4096
nuxt generate 动态路由未生成未配置预渲染路由nitro.prerender.routes 中列出,或开启 crawlLinks
构建产物过大依赖未 Tree-shake使用 nuxt build --profile 分析,移除无用依赖
.output/ 被提交到 Git忘记加入 .gitignore.output*.output 加入 .gitignore
预设选择错误导致部署失败预设与部署平台不匹配确认预设与实际部署平台一致
preview 报错 "No build found"未先构建先运行 nuxt buildnuxt generate
构建慢文件监听或类型生成增加内存、用 --profile 分析瓶颈

知识脉络

text
模块系统 → 你在这里:构建命令

              ├─→ 下一步:预览(本地验证构建结果)

              ├─→ 下一步:部署平台(选择部署方案)

              └─→ 相关:环境变量(构建时注入配置)

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