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

Next.js无法用环境变量配置重写,如何实现环境依赖路由重写?

问题描述

我用Next.js做前端、Express.js做后端开发应用,开发阶段直接跑各自的开发服务器就能正常工作,但生产环境打算用Docker部署,这时候API地址得改成容器名(不是localhost),而且开发和生产环境要用不同端口。

开发阶段我硬编码了路由重写配置,代码如下:

const nextConfig = {
  reactStrictMode: true,
  async rewrites() {
    return [
      {
        source: "/api/:path*",
        destination: `http://localhost:5000/api/:path*`,
      },
      {
        source: "/auth/:path*",
        destination: `http://localhost:5000/auth/:path*`,
      },
    ];
  },
};

module.exports = nextConfig;

这个配置在开发环境没问题,但切换到生产环境时,我想基于环境变量设置重写的目标URL——开发环境指向http://localhost:5000/api,生产环境指向http://api:5100/api(对应Docker容器)。

查了相关内容后,发现Next.js的next.config.js里没法直接用环境变量,想问问有没有其他办法实现这种依赖环境的路由重写?

可行解决方案

方案1:使用自定义服务器(Custom Server)

用Express搭建自定义服务器替代Next.js默认服务器,在服务器层直接根据环境变量配置路由转发,完全绕过next.config.js的限制。

示例代码:

// server.js
const express = require('express');
const next = require('next');
const { createProxyMiddleware } = require('http-proxy-middleware');

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

// 从环境变量读取后端地址
const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:5000';

app.prepare().then(() => {
  const server = express();

  // 配置代理转发
  server.use('/api', createProxyMiddleware({
    target: API_BASE_URL,
    changeOrigin: true,
  }));
  server.use('/auth', createProxyMiddleware({
    target: API_BASE_URL,
    changeOrigin: true,
  }));

  // 处理Next.js页面路由
  server.all('*', (req, res) => {
    return handle(req, res);
  });

  server.listen(process.env.PORT || 3000, (err) => {
    if (err) throw err;
    console.log('Server ready');
  });
});

修改package.json启动脚本:

{
  "scripts": {
    "dev": "NODE_ENV=development API_BASE_URL=http://localhost:5000 node server.js",
    "build": "next build",
    "start": "NODE_ENV=production API_BASE_URL=http://api:5100 node server.js"
  }
}

Docker部署时,直接在容器环境变量中设置API_BASE_URL=http://api:5100即可。

方案2:用API路由作为转发中间层

在Next.js的pages/api目录下创建转发文件,把前端的API请求先转到Next.js的API路由,再由该路由转发到后端服务,这样就能在API路由文件里正常使用环境变量。

示例:创建pages/api/[...path].js

import { createProxyMiddleware } from 'http-proxy-middleware';

const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:5000';

const proxy = createProxyMiddleware({
  target: API_BASE_URL,
  changeOrigin: true,
  pathRewrite: {
    '^/api': '/api', // 保持路径一致
  },
});

export const config = {
  api: {
    bodyParser: false, // 禁用bodyParser,让代理处理请求体
    externalResolver: true,
  },
};

export default proxy;

同理,pages/auth/[...path].js可套用相同逻辑配置。

在环境变量中设置API_BASE_URL:开发环境设为http://localhost:5000,生产环境设为http://api:5100。注意这里是服务器端API路由,无需给变量加NEXT_PUBLIC_前缀。

方案3:构建时动态生成next.config.js

写一个Node.js脚本,根据当前环境变量生成对应的next.config.js文件,再执行Next.js构建命令。

示例脚本generate-next-config.js:

const fs = require('fs');

const API_BASE_URL = process.env.API_BASE_URL || 'http://localhost:5000';

const configContent = `
const nextConfig = {
  reactStrictMode: true,
  async rewrites() {
    return [
      {
        source: "/api/:path*",
        destination: "${API_BASE_URL}/api/:path*",
      },
      {
        source: "/auth/:path*",
        destination: "${API_BASE_URL}/auth/:path*",
      },
    ];
  },
};

module.exports = nextConfig;
`;

fs.writeFileSync('next.config.js', configContent.trim());

修改package.json脚本:

{
  "scripts": {
    "dev": "API_BASE_URL=http://localhost:5000 node generate-next-config.js && next dev",
    "build": "API_BASE_URL=http://api:5100 node generate-next-config.js && next build",
    "start": "next start"
  }
}

这样在开发或构建前,会先根据环境变量生成正确的next.config.js,完美适配不同环境的路由重写需求。

内容的提问来源于stack exchange,提问作者Aleister Crowley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:03:26