Next.js 在具有不同路径的代理下

Next.js under a proxy with different path

使用 next.js 版本 8.0.3 我不知道如何在具有不同子路径的代理下提供自定义服务器。

我在做:

npm run build && npm start

为了搭建和开启自定义服务器。

而不是打开 http://localhost:3000, I'm using a proxy with another subpath http://localhost:8000/example

代理很简单,复制一下:

proxy.js

const express = require('express')
const proxy = require('http-proxy-middleware')

const options = {
  target:'http://localhost:3000/',
}
const exampleProxy = proxy(options)
const app = express()

app.use('/example', exampleProxy)
app.listen(8000)

然后:

node proxy.js

但是,当我打开 http://localhost:8000/example url 正在加载主页但没有样式、静态、javascript...任何...

我怎样才能正确地做到这一点?

非常感谢!

作为警告,我首先要说我不相信 NextJS 可以很好地处理代理,尤其是在子路径上。

话虽这么说,但以下内容应该有效,但有局限性:

const express = require('express')
const proxy = require('http-proxy-middleware')

const options = {
  target:'http://localhost:3000/',
  pathRewrite: {
    '^/example': ''
  }
}
const exampleProxy = proxy(options)
const app = express()

app.use(['/example', '/_next', '/static'], exampleProxy)
app.listen(8000)

pathRewrite 选项确保代理上的 /example/xyz 重定向到 NextJS 服务器上的 /xyz

您需要代理 /_next 或您将构建目录重命名为 的任何内容)以便您的页面找到所有构建的资产(脚本、样式表、webpack 块) , ETC。)。如果您检查 Next 的任何项目页面,您会发现这些资产 link 是绝对的,因此也需要代理该目录。

出于同样的原因,您需要代理 /static,除了该目录用于保存您的静态 NextJS 资产(图像等)。

您还会注意到您在 Next 中的页面 link 通常也是绝对的(我知道我的页面在我的所有项目中)。

以上就是我所说的原因,在我看来,NextJS 并不真正适合子路径代理使用。

更新:

您可以在 NextJS 项目根目录下的 next.config.js 文件中添加以下配置:

module.exports = {
  assetPrefix: '/example'
}

这会将 /example 添加到所有构建的资产中,因此您将 link 改为 /example/_next/pages/xyz 而不是 /_next/pages/xyz。通过此更新,您可以删除代理端的 /_next 代理,您的 可构建 资产(脚本、样式表等)仍应加载。

关于 NextJS 应用程序中的导航(即 'page')link,如我的评论所述,您可以设置自己的 Link 版本并添加子路径:

import Link from 'next/link'

// for proxied server
const PROXY_PATH= '/example'
// for non-proxied server
// const PROXY_PATH= ''

export default MyLink = ({ as, children, ...props }) => <Link {...props} as={`${PROXY_PATH}${as}`}>{children}</Link>

您必须确保所有 MyLink 组件都定义了 as 道具。你不想改变href道具本身(link因为它),只有as 道具(link 出现)。

最后,对于 /static 资产,您只需在 NextJS 应用程序中重写静态 links,即 turn

<img src='/static/mylogo.svg' />

<img src=`${PROXY_PATH}/static/mylogo.svg` />

并且代理端的路径重写应该可以正确处理。 有了这个,您可以在项目范围内在单独的配置文件中定义 PROXY_PATH 或从环境变量加载它。