跳到主要内容

nextjs-static-deploy


📦 Next.js 静态文件托管与部署全攻略

本文面向已经掌握了 Next.js 基本使用的开发者,重点介绍 /_next/staticpublic 目录的静态资源托管原理、部署方式,以及各种 CDN / 对象存储的优缺点与实施方案。


1. Next.js 静态资源的构成与原理

1.1 静态资源目录

Next.js 项目在构建后会生成两类静态资源:

  1. 构建产物静态资源(/_next/static)

    • 位置:构建后位于 .next/static 目录

    • 内容:编译打包的 JS/CSS 代码块、字体、运行时文件

    • 路径:部署后访问路径一般为

      https://yourdomain.com/_next/static/...
    • 特点:文件名带 hash,长期缓存安全

  2. 公共静态资源(/public)

    • 位置:public 文件夹(项目根目录)

    • 内容:开发者自己放的静态文件(图片、PDF、favicon 等)

    • 路径:保持目录结构直接映射到根路径

      /public/logo.png  →  https://yourdomain.com/logo.png
    • 特点:不会被 webpack 处理,文件名不变


2. 静态文件托管的几种常见方式

方案一:和应用同域部署(默认方式)

  • 描述:构建产物和 HTML/SSR 服务部署在同一服务器或平台(如 Vercel 默认部署)

  • 实现:

    • npm run build
    • 部署 .nextpublic 到应用服务器
  • 流程示例:

    • Vercel / Netlify 自动构建并托管静态文件
    • Nginx 直接提供静态文件服务

优点

  • 部署简单,零配置
  • 没有跨域问题
  • 自动保证版本一致性(HTML 和静态文件同一次构建)

缺点

  • 带宽消耗在主应用服务器
  • 全球访问延迟可能高(除非平台自带 CDN)

适用场景

  • 低访问量项目
  • 使用 Vercel、Netlify 这类自带 CDN 的平台

方案二:单独部署静态文件到 CDN/对象存储

  • 描述:将 /_next/staticpublic 文件上传到独立的 CDN 或对象存储(S3、Cloudflare R2、阿里 OSS),HTML 和 API 依然由主服务器提供。

  • 实现:

    • 构建后将 .next/static 上传到 https://cdn.example.com/_next/static

    • 配置 next.config.js

      module.exports = {
      assetPrefix: 'https://cdn.example.com',
      };
    • 公共资源 /public 也可上传到 CDN

优点

  • 静态资源走 CDN,减轻主服务器带宽压力
  • CDN 可全球加速,降低延迟
  • 高并发下稳定性更好

缺点

  • 构建后需额外同步步骤(上传到 CDN)
  • 必须保证版本一致性(新 HTML 必须引用新静态文件)
  • CDN 缓存更新策略要谨慎(需处理 hash 文件 & HTML 缓存)

适用场景

  • 高流量项目
  • 对延迟要求高,需要全球加速

方案三:版本化静态文件部署

  • 描述:在 CDN 上按版本号目录部署静态文件,每次构建不覆盖旧文件,HTML 切换到新版本

  • 实现:

    • 构建时生成 v123/_next/static/...

    • 配置 assetPrefix

      const version = process.env.BUILD_ID;
      module.exports = {
      assetPrefix: `https://cdn.example.com/${version}`,
      };
    • 新构建上传到 v124 目录,旧版本保留一段时间

优点

  • 可回滚版本
  • 缓存命中率高
  • 避免旧 HTML 访问 404

缺点

  • 存储占用较多(需定期清理旧版本)
  • assetPrefix 需构建时动态注入

适用场景

  • 需要高可用和回滚能力的大型项目
  • 用户可能长期持有旧 HTML 缓存

方案四:增量同步到 CDN

  • 描述:只上传有变化的静态文件到 CDN

  • 实现:

    • 使用 aws s3 syncrclone sync

      aws s3 sync .next/static s3://my-bucket/_next/static --exact-timestamps --delete
    • 不变的文件不会重复上传

优点

  • 部署速度快
  • 节省上传流量

缺点

  • 需要额外部署脚本
  • 某些对象存储的“同步删除”可能误删文件

适用场景

  • 大型项目,构建产物较大
  • 频繁部署,但大部分文件不变

方案五:纯静态导出部署(next export)

  • 描述:使用 next export 将整个站点导出为纯静态 HTML + JS/CSS

  • 实现:

    next build && next export

    会生成 out/ 目录,可直接上传到任意静态托管(GitHub Pages、Cloudflare Pages、Vercel)

优点

  • 无需 Node.js 服务器,部署超简单
  • 适合 CDN/静态站点托管

缺点

  • 不支持 SSR / ISR(只能生成纯静态页面)
  • 动态数据必须在前端请求 API

适用场景

  • 纯静态内容网站(博客、文档)
  • 无需服务端渲染

3. 各方案对比表

方案延迟带宽压力部署复杂度成本适用场景
同域部署小型项目 / Vercel 默认部署
独立 CDN 部署高流量 / 全球加速
版本化部署大型项目 / 需回滚
增量同步大文件项目 / 频繁更新
纯静态导出纯静态站点

4. 部署注意事项

  1. 版本一致性

    • 新 HTML 必须引用新静态文件
    • CDN 上旧文件需保留一段时间以防止 404
  2. 缓存策略

    • 静态文件可用长缓存(Cache-Control: max-age=31536000, immutable
    • HTML 页面需短缓存或禁用缓存(确保更新及时)
  3. 图片优化

    • next/image 默认走主服务处理,可切换到自定义 loader 走 CDN
  4. 自动化部署

    • 建议用 CI/CD(GitHub Actions、GitLab CI)自动构建并上传 CDN

    • 例如:

      - name: Build
      run: npm run build
      - name: Upload to S3
      run: aws s3 sync .next/static s3://my-bucket/_next/static --delete

5. 推荐选择

  • 个人/小型项目:直接用 Vercel / Netlify 全托管
  • 中大型项目/_next/static 独立 CDN 部署 + 主服务 SSR
  • 全球高访问量:版本化部署 + CDN + 回滚机制
  • 纯静态内容next export + 任意静态托管平台

总结一句话

Next.js 静态文件托管没有唯一的最佳方案,需要根据 流量规模、部署频率、成本、回滚需求 来选择。 小项目直接用平台托管,大项目建议 CDN 分离并配合版本管理,确保性能和可维护性。


“Next.js 静态文件部署架构图”, 直观展示不同方案下浏览器 → CDN → 主服务的请求流程。