Next.js 项目部署到 Nginx 子路径下,针对子路径进行配置

236 阅读2分钟

前置工作

先用 PM2 将 Next.js 项目运行在 3000 端口。

配置 Nginx

直接按照以往的经验,配置了子路径的代理:

location ^~ /chat/ {
  proxy_pass http://127.0.0.1:3000/;
  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
}

测试后出现了种种路径上的问题,比如打包后的js、css等静态资源 404,等等。

经过一番激烈的查找资料、搜索调试后,发现 Nginx 配置和 Next.js 项目配置都存在问题,需要进行调整。

Nginx 配置调整

调整后的 Nginx 配置如下:

location ^~ /chat {
  proxy_pass http://127.0.0.1:3000;
  proxy_set_header Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
}

注意,配置与之前存在的细微差别:

  • ^~ /chat/ 变成了 ^~ /chat,少了一个 “/
  • proxy_pass http://127.0.0.1:3000/ 变成了 proxy_pass http://127.0.0.1:3000,也少了一个 “/

这样配置与之前配置的区别是,之前带着 “/” 的配置,Nginx 在转发时会去掉子路径,而新配置会在转发时带着子路径。举个例子,比如请求的是 abc.com/chat/api

  • 带 “/” 的配置会转发到 http://127.0.0.1:3000/api
  • 不带 “/” 的配置会转发到 http://127.0.0.1:3000/chat/api

这样做的本质就是把子路径也扔给 Next.js 去处理,Nginx 只起一个纯转发的作用,不对请求做任何处理。

接下来需要调整 Next.js 项目的配置。

Next.js 项目配置调整

  1. 在 .env 文件中添加 basePath
NEXT_PUBLIC_APP_BASE_PATH=/chat

注意,环境变量名称要以 “NEXT_PUBLIC_” 开头,让服务端代码和客户端代码中都能访问此环境变量,不以“NEXT_PUBLIC”开头的环境变量只能在服务端代码中访问。

  1. 调整 next.config.js 添加 basePath
const BASE_PATH = process.env.NEXT_PUBLIC_APP_BASE_PATH;

/** @type {import('next').NextConfig} */
const nextConfig = {
  basePath: BASE_PATH,
};

export default nextConfig;
  1. 调整项目中所有的静态资源请求路径,以及所有的 api 请求路径,在其前面都加上基础路径 “/chat”,注意是 所有

这里直接定义一个常量,其它用到的地方直接导入使用即可:

/** Next App 全局的 basePath, 与 next.config.js 中的 basePath 一致 */
export const APP_BASE_PATH = `${process.env.NEXT_PUBLIC_APP_BASE_PATH}`;

/** api 请求的 Base URL */
export const API_BASE_URL = `${APP_BASE_PATH}/api`;

重新部署 Next.js 应用

重新编译部署,直接访问 Nginx 的子路径 abc.com/chat ,大功告成。