You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Express/NestJS单体后端部署Next.js静态导出产物?

解决Next.js 13.2静态导出部署+Express/NestJS单体服务器方案

先澄清静态产物的结构问题

执行next build && next export后,静态产物默认生成在out目录下,根路由对应的就是out/index.html,其他路由会以out/xxx/index.html的形式存在。直接查看out目录的文件结构就能找到这些文件,大概率是你没找对目录位置。

另外要检查next.config.js的配置是否正确,确保output: 'export'放在顶层配置里:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  // 其他配置项...
}

module.exports = nextConfig

一、Express实现单体服务器(处理API+托管SPA)

1. 安装依赖

确保已安装express和serve-static:

npm install express serve-static

2. 编写服务器代码(示例文件:server.js)

const express = require('express');
const serveStatic = require('serve-static');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;

// 托管Next.js静态导出产物
app.use(serveStatic(path.join(__dirname, 'out'), {
  index: ['index.html'],
}));

// 处理API请求示例
app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello from Express API!' });
});

// SPA路由 fallback:所有未匹配的路由返回根index.html
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'out', 'index.html'));
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

3. 启动服务器

node server.js

二、NestJS实现单体服务器(处理API+托管SPA)

1. 安装依赖

安装@nestjs/serve-static:

npm install @nestjs/serve-static

2. 配置静态托管(修改app.module.ts)

import { Module } from '@nestjs/common';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'out'), // 指向Next.js导出的out目录
      exclude: ['/api*'], // 排除API路由,交给NestJS处理
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

3. 添加SPA Fallback中间件

创建spa-fallback.middleware.ts:

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from 'express';
import { join } from 'path';

@Injectable()
export class SpaFallbackMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: () => void) {
    // 非API、非静态文件请求,返回index.html
    if (!req.path.startsWith('/api') && !req.path.includes('.')) {
      res.sendFile(join(__dirname, '..', 'out', 'index.html'));
    } else {
      next();
    }
  }
}

在app.module.ts中注册中间件:

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { SpaFallbackMiddleware } from './spa-fallback.middleware';
// 其他导入项...

@Module({
  // 已有配置...
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(SpaFallbackMiddleware).forRoutes('*');
  }
}

4. 编写API示例(app.controller.ts)

import { Controller, Get } from '@nestjs/common';

@Controller()
export class AppController {
  @Get('api/hello')
  getHello(): { message: string } {
    return { message: 'Hello from NestJS API!' };
  }
}

5. 启动NestJS服务器

npm run start:prod

关键注意事项

  • Next.js静态导出模式下,不能使用Server Components、内置API Routes、图片优化等依赖服务器的功能,这些会在导出时失效,所有API逻辑必须放在Express/NestJS中实现。
  • 确保next build && next export执行无报错,否则out目录可能生成不完整。

内容的提问来源于stack exchange,提问作者victor.ja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:55:25