Next.js 维护指南:保持您的应用程序健康并走在前面

自从 Next.js 版本 9 以来,我一直在维护 Next.js 应用程序。其中一些应用程序仍在生产中运行,服务数百万个请求。其他的呢?它们成了升级噩梦,因为某个人(好吧,有时是我)在六个月内跳过了维护,突然面临 47 个主要版本碰撞、三个已弃用的 API 和一个让安全团队失眠的 CVE。

Next.js 发展迅速。该框架在 2024 年和 2025 年大约每六个月发布一次主要版本,2026 年继续这种速度。如果您不积极维护您的 Next.js 项目,您会积累技术债务,其增长速度比您预期的要快。本指南涵盖了我学到的关于保持 Next.js 应用程序健康的一切知识,从每周的依赖项检查到年度主要版本迁移。如果您已经知道需要帮助,提交您的 RFP,我们会看一下。

目录

为什么 Next.js 维护比您想象的更重要

让我用一些数字来说明。根据 Snyk 的 2025 年开源安全状况报告,平均 JavaScript 项目有 49 个直接依赖项和超过 500 个传递依赖项。每个都是潜在的攻击面。2025 年,漏洞发布和野外出现漏洞利用之间的中位时间下降到 7 天。七天。

Next.js 具体引入了 vanilla React 应用程序没有的维护注意事项:

  • 服务端渲染攻击面 -- 您的 Next.js 应用在服务器上运行代码,而不仅仅在浏览器中。服务端的易受攻击依赖项比沙箱中的浏览器危险得多。
  • API 路由和服务器操作 -- 这些是完整的后端端点。它们需要与任何 Express 或 Fastify API 相同的安全严格性。
  • 构建管道依赖项 -- SWC、webpack/Turbopack、PostCSS 处理器和图像优化都有自己的依赖项树。
  • 中间件执行 -- 在许多部署中在边缘运行,具有自己的兼容性和安全考虑。

除了安全性外,还有 SEO 角度。Google 的核心网络生命力是排名因素,过时代码导致的 Next.js 性能下降可能会直接影响您的搜索可见性。我们看到 Social Animal 的客户仅通过从 Next.js 13 升级到 15 并修复累积的性能问题就恢复了 15-20% 的失落有机流量。

建立一个真正有效的维护时间表

我在维护数十个 Next.js 项目后获得的关键见解:维护在枯燥和例行公事时更容易。当它成为"项目"的那一刻,就是它已经逾期的那一刻。

这是我使用的时间表:

频率 任务 时间估计
每周 审查 Dependabot/Renovate PR,合并补丁更新 30-60 分钟
每两周 运行 npm audit 并解决发现 30 分钟
每月 更新次要版本,审查变更日志以查找破坏性变更 2-4 小时
每季度 审计未使用的依赖项,审查包大小,更新 Node.js 4-8 小时
每个版本 主要 Next.js 版本迁移 8-40 小时
每年 全面安全审计,依赖项检修,基础设施审查 16-40 小时

每周的节奏

每个星期一早上,我检查 Renovate 或 Dependabot 等工具打开的自动化 PR。补丁更新(1.2.3 → 1.2.4)在 CI 通过后合并。这最多需要 30 分钟,并防止"200 个过时包"的情况。

# 我每周运行的快速健康检查
npx npm-check-updates --target patch
npm audit --audit-level=moderate
npx next info

每月深入探讨

每月一次,我看次要版本碰撞。这些可以包括新功能,但不应该破坏现有的 API。强调"不应该"。始终阅读更新日志。

# 检查次要更新
npx npm-check-updates --target minor

# 预览将更改内容
npx npm-check-updates --target minor --format group

我将相关更新分组在一起。单独更新 @next/fontnext 是自找麻烦。它们应该同步移动。

依赖项升级:分步过程

大多数团队在这里出错。他们运行 npm update,祈祷,然后推送。这是我实际做的:

第 1 步:了解您所拥有的

在升级任何东西之前,了解您的依赖项景观。

# 列出所有过时的包及其详细信息
npm outdated

# 为特定包生成依赖项树
npm ls react-dom

# 检查您的锁文件中的重复项
npx depcheck

第 2 步:按风险对更新进行分类

不是所有更新都是相等的。我将它们分类为几个桶:

风险级别 示例 方法
补丁更新、仅开发依赖项、类型定义更新 批量合并
运行时依赖项中的次要版本碰撞、Next.js 补丁更新 单独更新、运行完整的测试套件
主要版本碰撞、Next.js 次要/主要更新、React 更新 专用分支、彻底测试、分阶段推出
严重 运行时依赖项的安全补丁 同日更新、紧急流程

第 3 步:创建隔离分支

对于超过补丁更新的任何内容:

git checkout -b deps/update-2026-05

# 更新特定包
npm install next@latest react@latest react-dom@latest

# 立即运行构建 -- 不要等待
npm run build

# 运行测试套件
npm test

# 检查 TypeScript 错误(如果使用)
npx tsc --noEmit

第 4 步:验证运行时行为

我们去年在一个客户现场碰到了这个:构建通过了,测试是绿色的,纸面上一切看起来都很好。然后服务器组件开始在生产中抛出水合不匹配,因为一个依赖项在次要碰撞中改变了其输出格式。通过的构建和测试并不意味着一切都有效。

我总是:

  1. 运行开发服务器并手动点击关键路径
  2. 检查服务器组件是否仍然正确呈现(水合不匹配喜欢隐藏)
  3. 验证 API 路由返回预期的响应
  4. 测试中间件行为,特别是身份验证流
  5. 检查图像优化是否仍然有效(next/image 组件在更新中有过中断)

如果您正在中间范围这类工作并需要一个团队支持,发送我们您的 RFP,我们可以一起找出正确的方法。

第 5 步:部署后监控

不要合并后就忘记。在部署依赖项更新后的 48 小时内监视您的错误跟踪(Sentry、LogRocket)和性能监控。

2026 年 Next.js 安全加固

Next.js 中的安全性已经大幅发展。Next.js 14 中引入的服务器操作模型,并通过 15 和 16 成熟,完全改变了攻击面。以下是现在要关注的内容。

服务器操作安全

服务器操作本质上是公共 API 端点。这样对待它们。

// 不好 -- 没有验证,没有身份验证检查
'use server'
export async function deleteUser(userId: string) {
  await db.user.delete({ where: { id: userId } })
}

// 好 -- 已验证、已身份验证、已授权
'use server'
import { z } from 'zod'
import { auth } from '@/lib/auth'

const deleteUserSchema = z.object({
  userId: z.string().uuid(),
})

export async function deleteUser(rawData: unknown) {
  const session = await auth()
  if (!session?.user) throw new Error('Unauthorized')
  
  const { userId } = deleteUserSchema.parse(rawData)
  
  // 检查用户是否有权限删除该特定用户
  if (session.user.role !== 'admin') throw new Error('Forbidden')
  
  await db.user.delete({ where: { id: userId } })
  revalidatePath('/admin/users')
}

安全标头

您的 next.config.js(或 2026 年的 next.config.ts -- TypeScript 配置自 Next.js 15 以来一直稳定)应该设置安全标头:

// next.config.ts
import type { NextConfig } from 'next'

const securityHeaders = [
  { key: 'X-DNS-Prefetch-Control', value: 'on' },
  { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
  { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
  { key: 'X-Content-Type-Options', value: 'nosniff' },
  { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
  { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
]

const config: NextConfig = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: securityHeaders,
      },
    ]
  },
}

export default config

内容安全策略

CSP 在 Next.js 中更困难,因为水合有内联脚本。基于 nonce 的方法效果最好:

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
  const cspHeader = `
    default-src 'self';
    script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
    style-src 'self' 'nonce-${nonce}';
    img-src 'self' blob: data:;
    font-src 'self';
    object-src 'none';
    base-uri 'self';
    form-action 'self';
    frame-ancestors 'none';
    upgrade-insecure-requests;
  `
  
  const response = NextResponse.next()
  response.headers.set('Content-Security-Policy', cspHeader.replace(/\s{2,}/g, ' ').trim())
  response.headers.set('x-nonce', nonce)
  return response
}

npm 审计工作流程

不要只是运行 npm audit。系统地处理结果:

# 生成 JSON 报告以供跟踪
npm audit --json > audit-report.json

# 修复可以自动修复的内容
npm audit fix

# 对于需要主要碰撞的顽固问题
npm audit fix --force  # 小心使用这个

# 检查特定包中的已知漏洞
npx is-my-node-vulnerable

对于修复尚未可用的包,请在 package.json 中使用 npm audit 覆盖:

{
  "overrides": {
    "vulnerable-transitive-dep": ">=2.1.1"
  }
}

自动化工具和 CI/CD 集成

自动化是将维护良好的团队与维护不良的团队区分开来的原因。以下是我 2026 年的堆栈:

Renovate Bot 配置

对于 Next.js 项目,我更喜欢 Renovate 而不是 Dependabot。它更可配置,对单一存储库的支持更好。

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "schedule": ["every weekend"],
  "packageRules": [
    {
      "matchPackageNames": ["next", "react", "react-dom", "@types/react", "@types/react-dom"],
      "groupName": "React + Next.js core",
      "automerge": false
    },
    {
      "matchUpdateTypes": ["patch"],
      "matchPackagePatterns": ["eslint", "prettier", "@types/"],
      "automerge": true,
      "automergeType": "branch"
    },
    {
      "matchPackagePatterns": ["*"],
      "matchUpdateTypes": ["major"],
      "enabled": true,
      "automerge": false,
      "labels": ["major-update", "needs-review"]
    }
  ],
  "vulnerabilityAlerts": {
    "enabled": true,
    "labels": ["security"]
  }
}

依赖项更新的 CI 管道

当依赖项更改时,您的 CI 应该做的不仅仅是运行测试:

# .github/workflows/dependency-check.yml
name: Dependency Update Validation
on:
  pull_request:
    paths:
      - 'package.json'
      - 'package-lock.json'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - run: npm test
      - run: npm audit --audit-level=high
      - name: Bundle size check
        run: npx size-limit
      - name: Lighthouse CI
        uses: treosh/lighthouse-ci-action@v12
        with:
          configPath: './lighthouserc.json'

Socket.dev 用于供应链安全

我为维护的每个项目都添加了 Socket.dev。它会捕获 npm audit 遗漏的内容,比如在新版本中突然添加网络调用或文件系统访问的包。它在我去年处理的项目中捕获了两个可疑更新。

处理主要 Next.js 版本迁移

主要版本迁移值得自己单独开设一个部分,因为它们是最耗时和最危险的维护任务。

迁移剧本

  1. 完整阅读官方迁移指南才能写任何代码。Vercel 为每个主要版本发布详细的代码模组和指南。

  2. 首先运行代码模组。 Next.js 提供自动代码模组来处理大多数重命名和 API 更改:

npx @next/codemod@latest upgrade
  1. 修复编译器错误。 运行代码模组后,运行 TypeScript 编译并修复损坏的内容。

  2. 测试服务器组件和客户端组件边界。 主要版本经常改变组件类型周围的默认行为。

  3. 验证数据获取模式。getServerSideProps 转移到服务器组件是 Next.js 有史以来最大的破坏性更改(Next.js 13)。后续版本继续完善这一领域。

  4. 更新您的部署配置。 Vercel 自动处理这个,但如果您自行托管或使用不同的平台,您需要更新 Dockerfile、构建脚本或无服务器配置。

2026 年版本特定说明

迁移 关键更改 估计工作量(中型应用程序)
Next.js 14 → 15 异步请求 API、React 19、Turbopack 稳定 16-24 小时
Next.js 15 → 16 更新的缓存默认值、React 编译器集成 8-16 小时

如果您仍在运行 Next.js 13 或更早版本,认真考虑分阶段迁移还是全新重建更有意义。我们在 Social Animal 帮助团队做出这个决定。有时诚实的答案是"重新开始"。

性能监控作为维护

维护不仅仅是保持依赖项最新。它是关于在用户(和 Google)注意到之前捕获性能下降。

监控内容

  • 核心网络生命力:LCP、CLS、INP(互动到下一绘制在 2024 年替换了 FID)。使用 Vercel Analytics、Google Search Console 或 CrUX 数据。
  • 构建时间:如果您的构建时间在三个月内翻倍,就有问题了。在 CI 中跟踪它。
  • 包大小:用 @next/bundle-analyzersize-limit 设置预算。
  • 服务器响应时间:特别是对于服务器组件和 API 路由。
  • 错误率:更新后的峰值表示下降。
# 向项目添加包分析
npm install @next/bundle-analyzer
// next.config.ts
import withBundleAnalyzer from '@next/bundle-analyzer'

const config = withBundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
})({
  // your config
})

export default config

运行 ANALYZE=true npm run build 每月一次并比较结果。不断增长的包大小通常指向在次要更新中添加了很多重量的依赖项。

何时重建与何时升级

这是没人想问的难题。以下是我的决策框架:

在以下情况下就地升级:

  • 您落后 1-2 个主要版本
  • 您的代码库遵循现代模式(App Router、服务器组件)
  • 测试覆盖关键路径
  • 团队理解现有的代码库

考虑重建时:

  • 您落后 3+ 个主要版本
  • 该应用程序仍在页面路由器上,您需要应用路由器功能
  • 超出依赖项的重大技术债务已累积
  • 原始架构不适合当前要求

考虑迁移到不同框架时:

  • 您的网站大多是静态的,Next.js 太过了(看看 Astro
  • 您在与 Next.js 模式作斗争而不是与它们配合工作
  • 您的团队在不同的堆栈中具有专业知识

如果您正在运行一个带有无头 CMS 的内容丰富的网站,有时 切换到专用架构 比维护一个已经超出其原始范围发展的 Next.js 应用程序节省更多时间。我们总是很乐意 坦诚地讨论选择

常见问题

我应该多久更新一次 Next.js 依赖项? 补丁更新应该每周进行。它们几乎总是安全的,通常包含安全修复。次要更新每月一次,审查变更日志后。主要版本应在稳定版发布后的 2-3 个月内进行,一旦生态系统有时间赶上。等待超过 6 个月进行主要版本会造成显著的升级困境。

使用 npm audit fix --force 是否安全? 不是,没有仔细审查。--force 标志允许依赖项中的主要版本碰撞,这可能会引入破坏性更改。我仅将其用作起点。在分支上运行它、构建、彻底测试,并在合并前审查 package-lock.json 中的每项更改。对于生产应用程序,手动更新特定易受攻击的包几乎总是更安全。

2026 年自动化 Next.js 依赖项更新的最佳工具是什么? Renovate Bot 是我的最佳选择。它处理分组更新(保持 nextreactreact-dom 同步),支持低风险更新的自动合并,并具有出色的单一存储库支持。Dependabot 对于更简单的设置也能很好地工作。Socket.dev 是一个额外的层级,对于供应链安全至关重要,无论您使用哪个更新工具。

我如何处理传递依赖项中的安全漏洞? 首先,检查更新直接依赖项是否修复了它,该依赖项拉动易受攻击的包。如果没有,请在 package.json(npm)或 resolutions(yarn)中使用 overrides 来强制特定版本。作为最后的手段,如果易受攻击性在您无法更新的包中,评估是否可以完全替换父依赖项或使用 patch-package 添加补丁。

当主要版本发布时,我应该立即升级到最新的 Next.js 版本吗? 不是对于生产应用程序。等待主要版本发布后 2-4 周以获得初始一轮错误修复。关注 Next.js GitHub 问题和 X/Twitter 上的社区以获取问题的早期报告。对于次要和补丁版本,您可以更积极。这些通常在发布后几天内是安全的。

如果我是独立开发者,我如何维护 Next.js 应用程序? 自动化是您最好的朋友。为补丁更新设置 Renovate Bot 并启用自动合并,配置 CI 在每个依赖项 PR 上运行构建和测试,并为每月手动审查预留一个固定的 2 小时块。我概述的时间表非常适合缩小规模。每周检查变成对自动化 PR 的 15 分钟扫描,每月深入探讨保持 2 小时。

2026 年我应该将 Node.js 的哪个版本与 Next.js 一起使用? Next.js 16 需要 Node.js 18.18 或更高版本,但我建议运行 Node.js 22 LTS(2024 年 10 月进入 LTS,支持到 2027 年 4 月)。Node.js 20 LTS 也没问题。除非您有特定的兼容性要求,否则避免 Node.js 18。它于 2025 年 4 月达到生命周期终止,不应再用于生产环境。

如果我们有内部开发者,支付专业维护是否值得? 这取决于您的团队带宽和专业知识。内部开发人员经常对维护工作的优先级较低,因为功能工作总是显得更紧迫。如果您的 Next.js 应用程序是业务关键的,并且您发现维护一直在滑坡,专门的 维护安排 与专门的团队确保它实际上得到完成。我们看到很多团队,延迟维护的成本远超过定期专业维护会花费的成本。准备好停止延迟了吗?获得 48 小时内的提案,让我们看看您的应用程序需要什么。