前置工作
先用 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 项目配置调整
- 在 .env 文件中添加 basePath
NEXT_PUBLIC_APP_BASE_PATH=/chat
注意,环境变量名称要以 “NEXT_PUBLIC_
” 开头,让服务端代码和客户端代码中都能访问此环境变量,不以“NEXT_PUBLIC”开头的环境变量只能在服务端代码中访问。
- 调整 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;
- 调整项目中所有的静态资源请求路径,以及所有的 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 ,大功告成。